I want to catch all unexpected Exceptions in a jersey rest service. Therefore i wrote an ExceptionMapper:
@Provider public class ExceptionMapper implements javax.ws.rs.ext.ExceptionMapper<Exception> { private static Logger logger = LogManager.getLogManager().getLogger(ExceptionMapper.class.getName()); @Override public Response toResponse(Exception e) { logger.log(Level.SEVERE, e.getMessage(), e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Internal error").type("text/plain").build(); } }
The mapper catches really all exceptions. Therefore i can't write:
public MyResult getById(@PathParam("id")) { if (checkAnyThing) { return new MyResult(); } else { throw new WebApplicationException(Response.Status.NOT_FOUND); } }
This is catched by the Mapper. Now i have to write:
public Response getById(@PathParam("id") { if (checkAnyThing) { { return Response.ok().entity(new MyResult()).build(); } else { return Response.status(Response.Status.NOT_FOUND).build(); } }
Is this the correct way to catch all unexpected exceptions and also return errors (error codes) in jersey? Or is there any other (more correct) way?
Exception handling is used to handle the exceptions. We can use try catch block to protect the code. Catch block is used to catch all types of exception. The keyword “catch” is used to catch exceptions.
If you catch some Exception types and don't do anything with the information, you have no chance of knowing what went wrong in those situations, but if you catch all Exception subclasses you have no chance of knowing what went wrong in a much large number of situations.
Yes, we can catch an error. The Throwable class is the superclass of all errors and exceptions in the Java language. Only objects that are instances of this class (or one of its subclasses) are thrown by the Java Virtual Machine or can be thrown by the throw statement.
WebApplicationException
has a getResponse
from which we can get the Response
. So you can check for a WebApplicationException
in your mapper. Maybe something like
@Override public Response toResponse(Throwable error) { Response response; if (error instanceof WebApplicationException) { WebApplicationException webEx = (WebApplicationException)error; response = webEx.getResponse(); } else { response = Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("Internal error").type("text/plain").build(); } return response; }
That way an instance of WebApplicationException
thrown will just return the default response. This will actually handle some other exceptions also, not thrown explictly by your application. WebApplicationException
has a few other exception under its hierarchy that are thrown by JAX-RS, for which predefined response/status codes are wrapped.
Exception Status code Description ------------------------------------------------------------------------------- BadRequestException 400 Malformed message NotAuthorizedException 401 Authentication failure ForbiddenException 403 Not permitted to access NotFoundException 404 Couldn’t find resource NotAllowedException 405 HTTP method not supported NotAcceptableException 406 Client media type requested not supported NotSupportedException 415 Client posted media type not supported InternalServerErrorException 500 General server error ServiceUnavailableException 503 Server is temporarily unavailable or busy
That being said, we could explicitly throw any of these exceptions in our code, just to give it more semantic value.
Generally speaking though, the example above may be unnecessary, unless you want to alter the response message/status code, as one can from the table above, the hierarchy of exceptions already have some general mapping. And in most cases, unexpected exceptions will already be mapped to InternalServerErrorException
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