Я получаю ответы на сервисный звонок через 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());
В том же духе, есть ли способ реплицировать гуаву 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);
});