Correctness39 - SpotBugsExtensionForSpringFrameWork/CS5098 GitHub Wiki
Correctness - Using Try-Catch Block to handle @Async exception with return type void
Description
Since we known that @ExceptionHandler
can not handle @Async
method, we'd need to use a different way to deal with it. However, we should not use try-catch block for those asynchronous methods with return type void
.
Methods annotated by @Async
means they are asynchronous methods which will create a new thread to process their logic. In this case, using try-catch block in the @Controller
level can not proceed the exception propagated by the @Component
class.
@Component
TaskFactory:
@Component
public class TaskFactory {
@Async
public void asyncTask1(int index) throws InterruptedException {
int a = 1;
int b = 0;
int c;
c = a/b;
System.out.println("C value is "+c);
}
...
}
@Controller
:
@RestController
public class TestController {
@Autowired
TaskFactory taskFactory;
@RequestMapping(value = "/welcome", method = RequestMethod.GET)
public String welcome() throws InterruptedException {
try{
taskFactory.asyncTask1(i);
} catch(ArithmeticException e) {
System.out.println("Exception handled.")
}
return "success";
}
}
In this scenario, exception will not be handled.
Theory
In synchronous cases, a thrown exception is propagated up the call stack until an appropriate handler is found. As shown is Figure 1, the synchronous method with an exception will be handle by the @Controller
class.[Exception Handling during Asynchronous Method Invocation - paper]
However, that's not the case in asynchronous method. With @Async
annotation, the exception thrown by the method is propagated through the call stack of its thread until the corresponding handler is acquired, as shown in Figure 2.[Unobtrusive Asynchronous Exception Handling with Standard Java Try/Catch Blocks] As the Figure 2 described, the @Async
method can not reach the try-catch block inside @Controller
because of the disconnection of call stacks (the preceding call stack is not accessible).
Solution
To address this problem, Spring provide AsyncUncaughtExceptionHandler
interface to help solve exception handling.
Link
Exception Handling during Asynchronous Method Invocation
Unobtrusive Asynchronous Exception Handling with Standard Java Try/Catch Blocks