Logging REST Exceptions with Spring

Logging REST Exceptions with Spring using ResponseEntityExceptionHandler.

Jeff Sheets

To enable logging for REST errors in Spring when using a ResponseEntityExceptionHandler just enable debug on ExceptionHandlerExceptionResolver

# See handled exceptions in the log file
log4j.logger.org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver=debug

Without setting debug to true, your errors will still be handled perfectly but you will not receive any messages in your server logs about the handled error.

Of course, there’s also a complicated way to register an extended ExceptionHandlerExceptionResolver and set the warnLogCategory. But that is too much work when you can just enable debug logging to get a nice message like this:

DEBUG 15 Oct 2014 09:03:58,391 (AbstractHandlerExceptionResolver.java:134) - Resolving exception from handler [null]: org.springframework.web.bind.UnsatisfiedServletRequestParameterException: Parameter conditions “startDay” not met for actual request parameters:

And if you aren’t already using it, you can easily handle any REST exceptions from your Spring Controllers with a @ControllerAdvice annotated class that extends ResponseEntityExceptionHandler. Here is an example RestResponseEntityExceptionHandler that I use:

/**
 * REST exception handlers defined at a global level for the application
 */
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(RestResponseEntityExceptionHandler.class);

    /**
     * Catch all for any other exceptions...
     */
    @ExceptionHandler({ Exception.class })
    @ResponseBody
    public ResponseEntity<?> handleAnyException(Exception e) {
        return errorResponse(e, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    /**
     * Handle failures commonly thrown from code
     */
    @ExceptionHandler({ InvocationTargetException.class, IllegalArgumentException.class, ClassCastException.class,
            ConversionFailedException.class })
    @ResponseBody
    public ResponseEntity handleMiscFailures(Throwable t) {
        return errorResponse(t, HttpStatus.BAD_REQUEST);
    }

    /**
     * Send a 409 Conflict in case of concurrent modification
     */
    @ExceptionHandler({ ObjectOptimisticLockingFailureException.class, OptimisticLockingFailureException.class,
            DataIntegrityViolationException.class })
    @ResponseBody
    public ResponseEntity handleConflict(Exception ex) {
        return errorResponse(ex, HttpStatus.CONFLICT);
    }

    protected ResponseEntity<ExceptionMessage> errorResponse(Throwable throwable,
                                                                                HttpStatus status) {
        if (null != throwable) {
            log.error("error caught: " + throwable.getMessage(), throwable);
            return response(new ExceptionMessage(throwable), status);
        } else {
            log.error("unknown error caught in RESTController, {}", status);
            return response(null, status);
        }
    }

    protected <T> ResponseEntity<T> response(T body, HttpStatus status) {
        log.debug("Responding with a status of {}", status);
        return new ResponseEntity<>(body, new HttpHeaders(), status);
    }
}

Share this Post

Related Blog Posts

JVM

GR8Conf US Recap: Why Your Company Should Adopt Groovy!

August 25th, 2014

At the 2014 GR8Conf US, Scott Hickey from Object Partners and Jim McGill from Mutual of Omaha spoke about a large mission-critical Groovy application.

Object Partners
JVM

Static website generation in Groovy

July 29th, 2014

Grain is a static site generator written in Groovy

Mike Hostetler
JVM

Grails API Functional Testing

July 15th, 2014

Examples of testing Grails APIs with Grails Rest Client Builder, Groovy Http Builder, and Apache Http Client

Object Partners

About the author

Jeff Sheets

Chief Software Technologist

Jeff has developed Java, Groovy, Grails, and Javascript web apps for industries as varied as Defense, Energy, Weather, Insurance, and Telecom. He is a co-organizer of the Omaha Java Users Group. Jeff has worked on Grails projects since the Grails 1.3.x days, and has experience with production Groovy code as well as Spock tests and Gradle builds. His latest focus has been on AngularJS and Spring Boot applications using JHipster. Jeff also enjoys volunteering at local CoderDojo events to teach programming to our next generation.