Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @Async abstraction is leaky regarding exception handling

Tags:

java

spring

When using Spring's @Async annotation, the abstraction is leaky when it comes to (checked) exceptions in the throws clause of the method. The compiler will force the caller to handle the exception, but in actuality the caller will never see exceptions thrown by the @Async method. Instead, depending on the implementation, it will be handled & logged by Spring, or given to a user-configured exception handler, or produced when Future#get() is called on the return value.

Therefore, I am forming the opinion that @Async methods should, as a rule, never throw checked exceptions. Instead, they should wrap all checked exceptions in types of RuntimeException so that no throws clause is present.

Is this an accurate evaluation? Is there any tooling or programming approach that fixes the leak? Does anybody happen to know what the Spring developers think of this, or if there are any plans to improve the situation? Thanks!

Possibly related: Spring Async method hides exceptions

like image 331
Shannon Avatar asked Jan 16 '15 21:01

Shannon


People also ask

How does @async works in Spring?

The @EnableAsync annotation switches on Spring's ability to run @Async methods in a background thread pool. This class also customizes the Executor by defining a new bean. Here, the method is named taskExecutor , since this is the specific method name for which Spring searches.

Does @async work on private method?

Never use @Async on top of a private method. In runtime, it will not able to create a proxy and, therefore, not work.

Can we use @async in same class?

@Async has two limitations: It must be applied to public methods only. Self-invocation — calling the async method from within the same class — won't work.

How does spring boot handle exceptions?

Exception HandlerThe @ExceptionHandler is an annotation used to handle the specific exceptions and sending the custom responses to the client. Define a class that extends the RuntimeException class. You can define the @ExceptionHandler method to handle the exceptions as shown.


1 Answers

Your evaluation is probably correct.

Now, if you want to handle the said exception, just do this:

@Async
void mangle() {
    try {
        doMangle();
    } catch (YourCheckedException e) {
        // Handle it
    }
}

void doMangle() throws YourCheckedException {
    ...
}
like image 147
Jukka Avatar answered Sep 27 '22 22:09

Jukka