Search code examples
springexceptionspring-bootexceptionhandler

Multiple error pages from the same ExceptionHandler


In my current spring-boot project, I have this ExceptionHandler:

@ControllerAdvice
public class GlobalDefaultExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception error) throws Exception {
        if (AnnotationUtils.findAnnotation(error.getClass(), ResponseStatus.class) != null)
            throw error;

        ModelAndView mav = new ModelAndView();
        mav.setAttribute("error", error);
        return mav;
    }

}

What I want to do it's make this handler redirect to different error pages, depending of origin the error.

I have two "types" of pages in my project: a public one, acessed both by an anonymous user or an authenticated user, and the admin pages (private), acessed only by authenticated users.

This two types of page have different styles. I want, when an error occurs when the user is in the public pages, an error page with the public style be shown. If the errors occurs when the user is in the private pages, another error page, with the style of the private pages be shown.


Solution

  • You can construct a selection of what exception classes it needs to throw in your controller , Assuming like this:

    @RequestMapping(value = "/check")
     public ModelAndView processUser( ) throws Exception {
            ModelAndView modelAndView = new ModelAndView();
    
            if (something... ) {
                throw new GlobalDefaultExceptionHandler( );  // throws GlobalDefaultExceptionHandler
            }
            if (something else... ) {
                throw new AnotherExceptionHandler( );// throws 'anotherExceptionHandler'
            }
    
         // If there isn't exception thrown....do something
    
     }
    

    And assuming this is the AnotherExceptionHandler class:

    @ControllerAdvice
    public class AnotherExceptionHandler{
    
        @ExceptionHandler(value = Exception.class)
        public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception error) throws Exception {
            if (AnnotationUtils.findAnnotation(error.getClass(), ResponseStatus.class) != null)
                throw error;
    
            // Go to another view
            ModelAndView mav = new ModelAndView();
            mav.setAttribute("anotherError", error);
            return mav;
        }
    
    }
    

    But if you are forced to use only an handler , you can just use selection directly just :

    @ControllerAdvice
    public class GlobalDefaultExceptionHandler {
    
        @ExceptionHandler(value = Exception.class)
        public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception error) throws Exception {
    
     ModelAndView mav =null;
    
            if ( // something...){
             mav = new ModelAndView()
             mav.setAttribute("error", ... );
             return mav;
              } 
    
             else if (// another something...){
               mav = new ModelAndView()
               mav.setAttribute("anotherError", ...);
               return mav;
              }
    
    return mav;
    
    }