Does quarkus provides an exception handler?
I wanted something like Spring's ControllerAdvice.
https://www.baeldung.com/exception-handling-for-rest-with-spring
In Quarkus, you can use the JAX-RS ExceptionMapper class to perform the necessary transformations between exceptions and your error response. The exception mapper infrastructure starts by catching Throwable, which is the ultimate superclass of all errors and exceptions, checked and unchecked.
The Global Exception Handler is a type of workflow designed to determine the project's behavior when encountering an execution error. Only one Global Exception Handler can be set per automation project.
What is RESTEasy Reactive? RESTEasy Reactive is a new JAX-RS implementation written from the ground up to work on our common Vert. x layer and is thus fully reactive, while also being very tightly integrated with Quarkus and consequently moving a lot of work to build time.
ExceptionMapper is a contract for a provider that maps Java exceptions to Response object. An implementation of ExceptionMapper interface must be annotated with @Provider to work correctly.
The equivalent in the Quarkus/RESTEasy world is called an ExceptionMapper
.
See here for instance: https://howtodoinjava.com/resteasy/resteasy-exceptionmapper-example/ .
We can use ExceptionMapper to handle custom exceptions.
javax.ws.rs.ext.ExceptionMapper
Interface ExceptionMapper<E extends Throwable>
defines a contract for a provider that maps Java exceptions E to Response.
Here is one simple example, Custom Exception Handling in Quarkus REST API
Custom Exception
import java.io.Serializable;
public class CustomException extends
RuntimeException implements Serializable {
private static final long serialVersionUID = 1L;
public CustomException() {
}
public CustomException(String message) {
super(message);
}
public CustomException(String message, Throwable cause) {
super(message, cause);
}
public CustomException(Throwable cause) {
super(cause);
}
public CustomException(String message, Throwable cause,
boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
Error Message
package org.knf.dev.demo.exception;
public class ErrorMessage {
private String message;
private Boolean status;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
public ErrorMessage(String message, Boolean status) {
super();
this.message = message;
this.status = status;
}
public ErrorMessage() {
super();
}
}
Custom Exception Handler
package org.knf.dev.demo.exception;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
@Provider
public class CustomExceptionHandler implements ExceptionMapper<CustomException> {
@ConfigProperty(name = "knowledgefactory.custom.error.msg.usernotfound")
String userNotFound;
@Override
public Response toResponse(CustomException e) {
if (e.getMessage().equalsIgnoreCase(userNotFound)) {
return Response.status(Response.Status.NOT_FOUND).
entity(new ErrorMessage(e.getMessage(), false)).build();
} else {
return Response.status(Response.Status.BAD_REQUEST).
entity(new ErrorMessage(e.getMessage(), false)).build();
}
}
}
Quarkus Endpoint:
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.knf.dev.demo.data.User;
import org.knf.dev.demo.data.UserData;
import org.knf.dev.demo.exception.CustomException;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
@Path("/api/v1")
public class UserController {
@ConfigProperty(name = "knowledgefactory.custom.error.msg.badrequest.numeric")
String idNumericErrorMsg;
@ConfigProperty(name = "knowledgefactory.custom.error.msg.usernotfound")
String userNotFound;
@Inject
UserData userData;
@GET
@Path("/users/{id}")
public Response findUserById(@PathParam("id") String id)
throws CustomException {
Long user_id = null;
try {
user_id = Long.parseLong(id);
} catch (NumberFormatException e) {
throw new CustomException(idNumericErrorMsg);
}
User user = userData.getUserById(user_id);
if (user == null) {
throw new CustomException(userNotFound);
}
return Response.ok().entity(userData.getUserById(user_id)).build();
}
}
Invalid Request (User Id not found):
Invalid Request(User Id must be numeric):
Valid request:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With