0

I have to handle exception globally so I am using Spring AOP @AfterThrowing.

Following is the code

@Component
public class SomeJob {
@Handled
@Scheduled(fixedRate = 5000)
public void doSomething() {
    System.out.println("Inside doSomething");
    Integer a=null;
    a.byteValue();
}}

.

@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Handled {}

Exception Handler

@Aspect
@Component
public class ExceptionHandlerAspect {
@Pointcut("@annotation(log.reduce.demo.aop.Handled)")
public void handledMethods() {
}

@AfterThrowing(pointcut = "handledMethods()", throwing = "ex")
public void handleTheException(Exception ex) {
    System.out.println("Inside handleTheException");
}}

Following is the output

Inside doSomething
Inside handleTheException
[2m2021-05-21 16:15:29.115[0;39m [31mERROR[0;39m [35m9044[0;39m [2m---[0;39m [2m[   scheduling-1][0;39m [36mo.s.s.s.TaskUtils$LoggingErrorHandler   [0;39m [2m:[0;39m Unexpected error occurred in scheduled task
java.lang.NullPointerException: null
at log.reduce.demo.aop.SomeJob.doSomething(SomeJob.java:13) ~[classes/:na]
at log.reduce.demo.aop.SomeJob$$FastClassBySpringCGLIB$$3f86fd70.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.6.jar:5.3.6]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779) ~[spring-aop-5.3.6.jar:5.3.6]
.
.
.
. java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_281]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_281]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_281]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_281]

How to avoid printing above stacktrace? I just want to log user define text when there is any exception something like below only

Inside doSomething
Inside handleTheException

Stacktrace is getting printed after handleTheException method execution completion. So how to skip/restrict that logging?

stackUser
  • 545
  • 3
  • 9
  • 21
  • @Tarmo its logging exception stacktrace the way when we dont catch or handle it....I want to skip/avoid that... – stackUser May 21 '21 at 11:33

2 Answers2

0

@AfterThrowing does not catch the exception. It can be used to add some side effects to already thrown exception, but not to catch it. Therefor it can't be used to prevent logging. If you want to catch the exception and prevent logging the stacktrace you need to create an @Around advice and surround the called method with try/catch.

There is a similar discussion with code examples here: Spring AOP AfterThrowing vs. Around Advice

Tarmo
  • 3,851
  • 2
  • 24
  • 41
0

As you can see the @ÀfterThrowing annotation does indeed invoke your handleTheException method when the exception is thrown but does so after the exception has been thrown (by which time it is too late to catch it.

On e solution could be to use @Around something like:

@Around(pointcut = "handledMethods()")
public void handleTheException(ProceedingJoinPoint pjp) {
    System.out.println("Inside handleTheException");
    try {
        pjp.proceed();
    }
    catch(Exception e) {
        // do something with e
    }

}}

This method will be entered before doSomething starts and uses the proceed()method to manually execute doSomething() at a time of your choosing, but now within a try...catch block allowing you to catch the exception and handle it yourself.

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-ataspectj-around-advice

willm
  • 31
  • 4