我正在通过 CompletableFuture 接收来自服务调用的响应。我想处理服务返回的一些已知异常——例如乐观并发控制冲突。
这就是我所拥有的。有没有更好的方法来做到这一点,它不包装异常或使用 SneakyThrows?包装异常意味着其他异常处理程序必须检查因果链,而不仅仅是使用instanceof
.
someService.call(request)
.handle((response, error) -> {
if (error == null)
return CompletableFuture.completedFuture(response);
else if (error instanceof OCCException)
return CompletableFuture.completedFuture(makeDefaultResponse());
CompletableFuture<Response> errorFuture = new CompletableFuture<>();
errorFuture.completeExceptionally(error);
return errorFuture;
}).thenCompose(Function.identity());
同样,有没有一种方法可以在没有 wrap-unwrap 的情况下复制番石榴的 withFallback ?
CompletableFuture<T> withFallback(CompletableFuture<T> future,
Function<Throwable, ? extends CompletableFuture<T>> fallback) {
return future.handle((response, error) -> {
if (error == null)
return CompletableFuture.completedFuture(response);
else
return fallback.apply(error);
}).thenCompose(Function.identity());
}
...
// Here's the first part of the question implemented using withFallback.
// It's a little cleaner, but it still requires wrapping as a future.
withFallback(someService.call(request), error -> {
if (error instanceof OCCException)
return CompletableFuture.completedFuture(makeDefaultResponse());
CompletableFuture<Response> errorFuture = new CompletableFuture<>();
errorFuture.completeExceptionally(error);
return errorFuture;
});
为了完整起见,如果我允许包装异常,这就是它的样子。(我有一个单元测试来验证抛出的异常沿链传播):
someService.call(request)
.exceptionally(error -> {
if (error instanceof OCCException)
return makeDefaultResponse();
else
// wrap because error is declared as a checked exception
throw new RuntimeException(error);
});