Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle exception thrown from ExceptionHandler in controller with ExceptionHandler in ControllerAdvice?

I have custom Exceptions extending Exception (MyException1, MyException2, MyException3)

@Controller
public class MyController {
    /*
       Method throwing MyException1
       Method throwing MyException2
       Method throwing MyException3
    */

    @ExceptionHandler(MyException1.class)
    public void handleMyException1(Exception ex){
        //Do something
        throw ex;
    }
    @ExceptionHandler(MyException2.class)
    public void handleMyException2(Exception ex){
        System.out.println("Exception Logged inside Controller")
    }
}

@ControllerAdvice
public class MyGlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public void handleAllException(Exception ex){
        System.out.println("Exception logged Outside Controller");
    }
}
My Intention: To log MyException1 from controller advice
              To log MyException2 inside handler in controller itself
              To log MyException3 from controller advice
MyException2 and MyException3 are working as intended but MyException1 fails with 
"Failed to invoke @ExceptionHandler method .....handleMyException1"
like image 575
Prashant Singh Rathore Avatar asked Nov 08 '16 11:11

Prashant Singh Rathore


1 Answers

You can pick one of the following options for your exception handling:

Option(1) : Remove @ExceptionHandler(MyException1.class) method from Controller so that it will be automatically handled by MyGlobalExceptionHandler.

Option(2) : Create MyException4 (which is a Wrapper for MyException1 with added information) & throw it from Controller as shown below:

@Controller
public class MyController {
    /*
       Method throwing MyException1
       Method throwing MyException2
       Method throwing MyException3
    */

    @ExceptionHandler(MyException1.class)
    public void handleMyException1(Exception ex){
         //MyException4 exe4 = new MyException4();
        // Add the required details to it
        throw exe4;
    }

    @ExceptionHandler(MyException2.class)
    public void handleMyException2(Exception ex){
        System.out.println("Exception Logged inside Controller")
    }
}

@ControllerAdvice
public class MyGlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public void handleAllException(Exception ex){
        System.out.println("Exception logged Outside Controller");
    }
}

P.S.: I did not add Option(3) here, which is manually invoking MyGlobalExceptionHandler's handleAllException() as It is not a good practice. Rather you should simply throw the exception and the @ExceptionHandler will take care automatically.

One more problem with the manual invocation is that at some point of time in future, it will be problematic to debug the exceptions as some of your flows manually call MyGlobalExceptionHandler and some flows are called by the framework.

like image 110
developer Avatar answered Oct 15 '22 14:10

developer