Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have a class annotated by ControllerAdvice to handle different types of exceptions?

I have a class called GlobalExceptionHandler that is annotated by ControllerAdvice. It properly handle all NoHandlerFoundExceptions. I added a new method to to handle InternalError exceptions but it does not handle such exceptions; therefore, I am still receiving HTTP Status 500.

Based on this link the exception class of 500 (Internal Server Error) is ConversionNotSupportedException.

I tried following codes but none of the catch Internal Server Error.

1

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String handleExceptionNotFound(NoHandlerFoundException ex) {
        System.err.println("not found");
        return "redirect:/error";
    }

    @ExceptionHandler(ConversionNotSupportedException.class)
//  @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String handleExceptionsInternalError(ConversionNotSupportedException ex) {
        ex.printStackTrace();
        System.err.println("internal error");
        return "redirect:/error";
    }

}

2

@ExceptionHandler(ConversionNotSupportedException.class)
public String handleExceptionsInternalError(HttpServletRequest req, ConversionNotSupportedException ex) {

3

@ExceptionHandler
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleExceptionsInternalError(ConversionNotSupportedException ex) {

Exception that I need to handle is as follows:

HTTP Status 500 - Could not resolve view with name 'user' in servlet with name 'myproject'
javax.servlet.ServletException: Could not resolve view with name 'user' in servlet with name 'myproject'
    org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1211)
    org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1011)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
like image 662
Daniel Newtown Avatar asked Jul 03 '15 02:07

Daniel Newtown


1 Answers

It looks like your exception handler is returning an invalid view, which results in an exception in the code that calls the exception handler. See DispatcherServlet.processDispatchResult

In this case the exception is thrown from the DispatcherServlet itself, and the only way to handle it is through web.xml

You need to fix your exception handler to return a valid view. The other answers to handle using @ExceptionHandler(Exception.class) are valid and can be used to handle exceptions thrown from your controllers.

Update: Based on the @Jack's comment that the exception is caused by a controller returning a view that does not exist (and not the exception handler as I originally thought). Once you return a view, the container calls the view resolver to render it and if that throws an exception, the exception handler will not be invoked (see this & this)- the easy solution is to handle it in web.xml.

Another option is to override the view resolver.resolveViewName, say you are using InternalResourceViewResolver which could look like this:

public class CustomViewResolver extends InternalResourceViewResolver {
    @Override
    public View resolveViewName(String viewName,
                            Locale locale) throws Exception {
        try{
            return super.resolveViewName();
        } catch (Exception ex) {
            //log
            return new InternalResourceView("urlForErrorView");
       }
    }
}
like image 64
6ton Avatar answered Sep 29 '22 13:09

6ton