【发布时间】:2021-06-17 17:31:29
【问题描述】:
我正在使用 completablefuture 进行并行调用,如下所示,
public Response getResponse() {
Response resultClass = new Response();
try {
CompletableFuture<Optional<ClassA>> classAFuture
= CompletableFuture.supplyAsync(() -> service.getClassA() );
CompletableFuture<ClassB> classBFuture
= CompletableFuture.supplyAsync(() -> {
try {
return service.getClassB();
}
catch (Exception e) {
throw new CompletionException(e);
}
});
CompletableFuture<Response> responseFuture =
CompletableFuture.allOf(classAFuture, classBFuture)
.thenApplyAsync(dummy -> {
if (classAFuture.join().isPresent() {
ClassA classA = classAFuture.join();
classA.setClassB(classBFuture.join());
response.setClassA(classA)
}
return response;
});
responseFuture.join();
} catch (CompletionExecution e) {
throw e;
}
return response;
}
我需要为return service.getClassB() 添加try catch,因为它会在getClassB 方法中引发异常。
现在我面临的问题是如果service.getClassB() 抛出错误,它总是包裹在java.util.concurrent.ExecutionException 中。在这种情况下,此方法会抛出 UserNameNotFoundException ,但它被包裹在 ExecutionException 中,并且它没有被捕获在正确的位置 @ControllerAdvice 异常处理程序类中。我尝试了使用 throwable 的不同选项,但没有帮助。
有没有很好的方法来处理异常并解包并将其发送到@ControllerAdvice 类?
【问题讨论】:
-
你不能为
ExecutionException创建一个@ControllerAdvice并在其中检查它的原因吗?通过Exception::getCause并将通常的UserNameNotFoundException和ExecutionException控制器建议委托给相同的通用逻辑? -
catch (CompletionExecution e) { throw e; }的意义何在?再接再扔的效果,就像当初没接住一样。所以你最终会抛出一个CompletionExecution,而不是ExecutionException。为什么操作的结果是一个不在范围内的变量(response)?应该是resultClass,你在方法开始时声明和初始化的变量? -
(注意:我在这里投了反对票,因为在这里写代码时引入了几个拼写错误。代码应该总是粘贴,以免犯这些可避免的错误。我对初学者很容易在这里,但不是 28K 用户)。
标签: spring-boot java-8 completable-future