Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC @ExceptionHandler method in controller never being invoked

I have a Spring MVC controller with some simple REST service requests. I would like to add some error handling when specific exceptions are thrown from my services, but I cannot get a handler method annotated with @ExceptionHandler to actually ever be called. Here is one service I am deliberately throwing an exception to try and get my handler method to take over. The handler method is never invoked and Spring just returns a 500 error to the calling client. Do you have any ideas on what I'm doing wrong?

@ExceptionHandler(IOException.class)
public ModelAndView handleIOException(IOException ex, HttpServletRequest request, HttpServletResponse response) {
    response.sendError(HttpServletResponse.SC_FORBIDDEN);
    System.out.println("It worked!");
    return new ModelAndView();
}

@RequestMapping(value = "/json/remove-service/{id}", method = RequestMethod.DELETE)
public void remove(@PathVariable("id") Long id) throws IOException {
    throw new IOException("The handler should take over from here!");
}
like image 378
11101101b Avatar asked Mar 28 '12 14:03

11101101b


People also ask

How does Spring handle global exception?

Global Exception Handler - Exception Handling is a cross-cutting concern, it should be done for all the pointcuts in our application. We have already looked into Spring AOP and that's why Spring provides @ControllerAdvice annotation that we can use with any class to define our global exception handler.

How does Spring controller handle exceptions?

Spring MVC provides exception handling for your web application to make sure you are sending your own exception page instead of the server-generated exception to the user. The @ExceptionHandler annotation is used to detect certain runtime exceptions and send responses according to the exception.

How do you implement controller advice?

@ControllerAdvice is a specialization of the @Component annotation which allows to handle exceptions across the whole application in one global handling component. It can be viewed as an interceptor of exceptions thrown by methods annotated with @RequestMapping and similar.

How do you handle an exception in spring boot using annotations?

The exception handler method takes in an exception or a list of exceptions as an argument that we want to handle in the defined method. We annotate the method with @ExceptionHandler and @ResponseStatus to define the exception we want to handle and the status code we want to return.


1 Answers

Frustratingly, I have suffered from this as well. I discovered that if you mistakenly implement Throwable instead of Exception the Exception resolver will just rethrow your Throwable as a IllegalStateException. This will fail to invoke your @ExceptionHandler.

If you've implemented Throwable instead of Exception try changing it to Exception instead.

Here's the code in question from InvocableHandlerMethod

catch (InvocationTargetException e) {
            // Unwrap for HandlerExceptionResolvers ...
            Throwable targetException = e.getTargetException();
            if (targetException instanceof RuntimeException) {
                throw (RuntimeException) targetException;
            }
            else if (targetException instanceof Error) {
                throw (Error) targetException;
            }
            else if (targetException instanceof Exception) {
                throw (Exception) targetException;
            }
            else {
                String msg = getInvocationErrorMessage("Failed to invoke controller method", args);
                throw new IllegalStateException(msg, targetException);
            }
        }
like image 194
Matt Friedman Avatar answered Oct 21 '22 14:10

Matt Friedman