How do I register a catch-all ExceptionMapper<Exception> that does not intercept WebApplicationException for which Jersey provides special handling?
UPDATE: I filed this feature request: http://java.net/jira/browse/JERSEY-1607
I ended up registering a ExceptionMapper:
import com.google.inject.Singleton;
import com.sun.jersey.api.container.MappableContainerException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
/**
* @author Gili Tzabari
*/
@Provider
@Singleton
public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException>
{
@Override
public Response toResponse(RuntimeException e)
{
if (e instanceof WebApplicationException)
{
// WORKAROUND: Attempt to mirror Jersey's built-in behavior.
// @see http://java.net/jira/browse/JERSEY-1607
WebApplicationException webApplicationException = (WebApplicationException) e;
return webApplicationException.getResponse();
}
// Jetty generates a log entry whenever an exception is thrown. If we don't register an
// ExceptionMapper, Jersey will log the exception a second time.
throw new MappableContainerException(e);
}
}
Take a look how it's done in ReXSL ExceptionTrap class. You don't register an ExceptionMapper to catch all exception un-caught by Jersey. Instead, you let them bubble up to the Servlet container (e.g. Tomcat), and the container will forward them to the right servlet for further handling.
The main and only purpose of ExceptionMapper is to convert certain business-specific exceptions to HTTP responses. In other words, let the application control exceptional flow of events. On the other hand, the purpose of servlet exception catching mechanism is to control application failover and do some post-mortem operations, like, for example, logging. In other words, ExceptionMapper works when you're still in control, while exception catching servlet helps when control is lost and you have to show 50x response code to the user.
Jetty logs (through JUL) every WebApplicationException if status code of its encapsulated Response is higher than 500. Runtime exceptions are not logged by Jetty, they just bubble up to the container.
Extend ExtendedExceptionMapper and implement isMappable(e):
@Override
public boolean isMappable(T e) {
return !e instanceof WebApplicationException;
}
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