我有以下情况:
// MyService:
@Async
public CompletableFuture<MyObject> findMyObjectAsync(){
// .... logic goes here
// if error happens:
return CompletableFuture.completeExceptionally(new IllegalStateException());
}
// MyController:
public CompletableFuture<MyObject> search(){
return myService.findMyObjectAsync();
}
因此,不是从控制器获取例外:IllegalStateException
,而是CompletionException
。
由于这种情况,异步拦截器:org.springframework.aop.interceptor.AsyncExecutionInterceptor#doSubmit
将异常包装在CompletionException
中。
然后ReturnValueHandler
中的CompletableFuture
:org.springframework.web.servlet.mvc.method.annotation.DeferredResultMethodReturnValueHandler
不会取消包装CompletionException
。
解决方法:
实际上,很多东西,例如return使用DeferredResult
或ListenableFuture
,或使用Callable
并完全避免使用@Async
和AsyncExecutionInterceptor
注释。
建议的解决方案:
在DeferredResultMethodReturnValueHandler
中检查异常是否包裹在CompletionException
中,然后将其展开。