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.
Practice
AsyncUncaughtExceptionHandler in Spring Boot asynchronous methods?Solution
Step 1: Understand async method return types
Async methods returning void cannot return exceptions directly to the caller.Step 2: Role of AsyncUncaughtExceptionHandler
This handler catches exceptions from void async methods to prevent app crashes.Final Answer:
To handle exceptions thrown by async methods that return void -> Option AQuick Check:
Void async exceptions need AsyncUncaughtExceptionHandler [OK]
- Thinking AsyncUncaughtExceptionHandler retries failed tasks
- Assuming it handles exceptions for Future-returning methods
- Confusing it with synchronous exception handling
Solution
Step 1: Identify async method return types
Async methods returning results should return Future or CompletableFuture to handle async results and exceptions.Step 2: Check method signatures
@Async public CompletableFuture<String> fetchData() { return CompletableFuture.completedFuture("data"); } returns CompletableFuture<String> correctly and does not declare checked exceptions, which is proper for async methods.Final Answer:
@Async public CompletableFuture<String> fetchData() { return CompletableFuture.completedFuture("data"); } -> Option DQuick Check:
Async methods with results use CompletableFuture [OK]
- Declaring async methods with void when result is needed
- Throwing checked exceptions directly in async methods
- Returning raw types instead of Future or CompletableFuture
CompletableFuture?Solution
Step 1: Analyze CompletableFuture exception handling
Theexceptionallymethod handles exceptions and provides fallback values.Step 2: Understand method behavior on exception
If an exception occurs,exceptionallyreturns the fallback value instead of propagating the exception.Final Answer:
The exception is caught insideexceptionallyand a fallback value is returned -> Option AQuick Check:
CompletableFuture.exceptionally handles exceptions [OK]
- Assuming exceptions crash the app without handling
- Expecting null return instead of fallback value
- Ignoring the need for exceptionally or handle methods
Future and explain why exceptions are not handled properly:
@Async
public Future<String> loadData() {
throw new RuntimeException("Failed");
}Solution
Step 1: Understand async method exception handling
Exceptions thrown directly in async methods returning Future are not propagated properly.Step 2: Proper way to handle exceptions in Future
Return a Future that completes exceptionally instead of throwing directly.Final Answer:
Throwing exception directly in async method causes it to be lost; should return Future with exception -> Option CQuick Check:
Throwing exceptions directly in async Future methods is incorrect [OK]
- Throwing exceptions directly in async methods returning Future
- Ignoring exception handling in async methods
- Misusing @Async annotation with incompatible return types
CompletableFuture<String> that may throw exceptions. How can you combine exception handling and fallback logic so the caller always gets a valid string without blocking?Solution
Step 1: Understand async exception handling with CompletableFuture
Thehandlemethod allows processing both result and exception without blocking.Step 2: Implement fallback logic in handle
Insidehandle, check if exception is present and return fallback string if so.Final Answer:
Usehandlemethod on CompletableFuture to catch exceptions and provide fallback value -> Option BQuick Check:
CompletableFuture.handle combines result and exception handling [OK]
- Blocking caller thread with get() defeats async purpose
- Trying to catch exceptions outside async context
- Declaring checked exceptions in async methods unnecessarily
Ready to prove it?
Pass the test and this pattern moves unknown
