AOP Exception Handling

后端 未结 4 838
迷失自我
迷失自我 2020-12-15 04:56

I see that Guice and Spring use AOP Alliance under the hood for method interceptions, and I\'ve been trying to figure out how to get AOP Alliance to intercept and handle cer

相关标签:
4条回答
  • 2020-12-15 05:37

    There's a reason that this doesn't exist. It would require rewriting the block structure of your code as if you'd written the try/catch block in the first place. This, it seems to me, potentially plays havoc with variable scope and other things. You're asking AOP to rewrite the byte code to be something like the following code, and that's quite a rewrite.

    HerpDerp hd = null;
    
    try {
        if(hd == null)
            throw new RuntimeException("Herpyl derp!");
    } catch(RuntimeException e) {
       if (someConditionIsMet) {
           throw e;
       }
    }
    
    Manny.pacquiao();
    
    0 讨论(0)
  • 2020-12-15 05:45

    @4herpsand7derpsago If what you're trying to do is to catch the thrown exception using AOP to perform various task to handle it and then comes back to the code where the exception originally thrown, I think you miss understand the concept of AOP.

    As you point out in your code

    HerpDerp hd = null;
    
    if(hd == null)
    throw new RuntimeException("Herpyl derp!");
    
    Manny.pacquiao();
    

    If you want AOP to catch your RuntimeException, perform some stuff to handle it and comes back to Manny.pacquiao();, the answer is you can't. The reason is because when the RuntimeException is thrown and caught by AOP, the stack is already at your AOP code. you can't comes back to execute Many.pacquiao();. The only way if you want to continue executing Many.pacquiao(); is by using try-finally block as follow

    HerpDerp hd = null;
    
    try {
        if(hd == null)
            throw new RuntimeException("Herpyl derp!");
    } finally {
        Manny.pacquiao();
    }
    

    Only then your Many.pacquiao() will get executed, but before your AOP catch the RuntimeException

    0 讨论(0)
  • 2020-12-15 05:48

    You can catch exceptions with Spring AOP, but I do not know if that matches your requirement for a pure Java framework.

    With Spring, you can write a simple AOP interceptor as something like:

    @Aspect
    public class ErrorInterceptor{
    @AfterThrowing(pointcut = "execution(* com.mycompany.package..* (..))", throwing = "ex")
    public void errorInterceptor(WidgetException ex) {
        if (logger.isDebugEnabled()) {
            logger.debug("Error Message Interceptor started");
        }
    
        // DO SOMETHING HERE WITH EX
        logger.debug( ex.getCause().getMessage());
    
    
        if (logger.isDebugEnabled()) {
            logger.debug("Error Message Interceptor finished.");
        }
    }
    }
    

    but there is no way to return to the calling method or continue processing on the subsequent line. However if you handle the exception here, it won't bubble up the chain unless you rethrow it yourself.

    0 讨论(0)
  • 2020-12-15 05:51

    To "catch" uncaught exceptions with AspectJ, you can use the following aspect:

    pointcut uncaughtExceptionScope() : 
        (execution(* com.mycompany.myrootpackage..Main.main(..)) 
        || execution(* java.util.concurrent.Callable+.call()) 
        || execution(* java.lang.Runnable+.run()) 
        ));
    
    after() throwing(Throwable t) : uncaughtExceptionScope() && !cflow(adviceexecution())    {
        handleException(thisJoinPoint, t);
    }   
    
    protected void handleException(JoinPoint jp, Throwable t)
    {
        // handle exception here
    }
    

    I do not think it is possible to "go back" to the execution point.

    0 讨论(0)
提交回复
热议问题