6

So I am trying to log all uncaught exceptions returned by the controllers of a spring project in a generic fashion. I was able to do this with the following exception handler:

@ControllerAdvice
public class ControllerConfig {

private final Logger logger = LoggerFactory.getLogger(this.getClass());

public static final String DEFAULT_ERROR_VIEW = "error";

@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public void handleBadRequest(HttpMessageNotReadableException e) {
    logger.warn("Returning HTTP 400 Bad Request", e);
    throw e;
}

@ExceptionHandler(AccessDeniedException.class)
public void defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception {
    logger.error("Error in request:" + request.getRequestURL(), e);
    throw e;
}

This also returns the error responses of the request, so I don't have to differentiate between all the different error response codes.

However, for every invocation of the method a second error log is created because of the exception thrown in the method: Code is from org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#doResolveHandlerMethodException

try {
        if (logger.isDebugEnabled()) {
            logger.debug("Invoking @ExceptionHandler method: " + exceptionHandlerMethod);
        }
        exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exception);
    }
    catch (Exception invocationEx) {
        if (logger.isErrorEnabled()) {
            logger.error("Failed to invoke @ExceptionHandler method: " + exceptionHandlerMethod, invocationEx);
        }
        return null;
    }

So is there a smarter way to return the original exception of the method?

0

1 Answer 1

1

It depends on what do you mean by "a smarter way to return the original exception". What exactly would you like to return to the client? If this is just the message of the exception you can simply return it from the exception handler and annotate the method with @ResponseBody. Spring will do the rest for you.

@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public String handleBadRequest(HttpMessageNotReadableException e) {
    logger.warn("Returning HTTP 400 Bad Request", e);
    throw e.getMessage();
}

You can also return some custom object which wraps the exception information and any other data that you desire.

Sign up to request clarification or add additional context in comments.

1 Comment

you can't throw string types. I think you want return e.getMessage();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.