Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey... how to log all exceptions, but still invoke ExceptionMappers

I'm in a little bit of bind... want my cake and to eat it too.

I want to log all exceptions my application throws. So if someone hits an incorrect URL, i want to log the stack trace to SLF4J.

So you're probably thinking, 'hey thats easy, just implement an exceptionmapper and log the exception." So I did:

public class RestExceptionMapper implements ExceptionMapper<java.lang.Exception> {
    private static final Logger log = LoggerFactory.getLogger(RestExceptionMapper.class);

    /**
     * {@inheritDoc}
     */
    @Override
    public Response toResponse(Exception exception) {
        log.error("toResponse() caught exception", exception);
        return null;
    }
}

If you do this, instead of 404 errors when someone types a wrong URL in, they get a 500 error. One would guess returning null would propagate the exception down the chain handlers, but Jersey doesn't do that. It actually provides very little info why it would choose one handler over another...

Has anyone ran into this problem and how did you solve it?

like image 826
Jonathan S. Fisher Avatar asked Apr 13 '14 20:04

Jonathan S. Fisher


1 Answers

You can use a RequestEventListener to listen for an exception event and log the throwable, without interfering with any existing processing. Note that this means first registering an ApplicationEventListener which then returns an instance of RequestEventListener. The following does both implemented in a single class:

@Provider
public class ExceptionLogger implements ApplicationEventListener, RequestEventListener {
    
    private static final Logger log = LoggerFactory.getLogger(RequestExceptionLogger.class);
    
    @Override
    public void onEvent(final ApplicationEvent applicationEvent) {
    }

    @Override
    public RequestEventListener onRequest(final RequestEvent requestEvent) {
        return this;
    }

    @Override
    public void onEvent(RequestEvent paramRequestEvent) {
        if(paramRequestEvent.getType() == Type.ON_EXCEPTION) {
            log.error("", paramRequestEvent.getException());
        }
    }
}
like image 129
Adrian Baker Avatar answered Nov 15 '22 20:11

Adrian Baker