When you run tasks in the background, errors can happen. Exception handling in async helps you catch and manage these errors so your app stays stable and you know what went wrong.
Exception handling in async in Spring Boot
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.annotation.EnableAsync; import java.lang.reflect.Method; @Configuration @EnableAsync public class AsyncConfig implements AsyncConfigurer { @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new AsyncUncaughtExceptionHandler() { @Override public void handleUncaughtException(Throwable ex, Method method, Object... params) { System.out.println("Exception message - " + ex.getMessage()); System.out.println("Method name - " + method.getName()); } }; } }
This configures how to handle exceptions thrown by async methods that return void.
For async methods returning Future or CompletableFuture, handle exceptions inside the returned object.
@Async
public void asyncMethod() {
throw new RuntimeException("Error in async task");
}@Async
public CompletableFuture<String> asyncMethodWithResult() {
if (true) {
CompletableFuture<String> future = new CompletableFuture<>();
future.completeExceptionally(new RuntimeException("Error in async task with result"));
return future;
}
return CompletableFuture.completedFuture("Success");
}This Spring Boot app runs an async method that throws an exception. The custom AsyncUncaughtExceptionHandler catches and prints the error message and method name.
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.annotation.EnableAsync; import java.lang.reflect.Method; @SpringBootApplication @EnableAsync public class AsyncExceptionDemoApplication implements AsyncConfigurer { public static void main(String[] args) { var context = SpringApplication.run(AsyncExceptionDemoApplication.class, args); AsyncExceptionDemoApplication app = context.getBean(AsyncExceptionDemoApplication.class); app.runAsyncTask(); } @Async public void runAsyncTask() { throw new RuntimeException("Something went wrong in async task"); } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new AsyncUncaughtExceptionHandler() { @Override public void handleUncaughtException(Throwable ex, Method method, Object... params) { System.out.println("Caught async exception: " + ex.getMessage()); System.out.println("In method: " + method.getName()); } }; } }
Exceptions in async methods returning void are caught by AsyncUncaughtExceptionHandler.
For async methods returning Future or CompletableFuture, handle exceptions by adding callbacks like .exceptionally().
Always enable async support with @EnableAsync on a configuration or main class.
Async exception handling keeps your app stable when background tasks fail.
Use AsyncUncaughtExceptionHandler for void async methods.
Handle exceptions inside Future or CompletableFuture for async methods with results.