CompletableFuture recoverWith equivalent? i.e. exceptionally but return CompletableFuture<U>
Solution 1:
Is this what you are looking for?
askPong("cause error")
.handle( (pong, ex) -> ex == null
? CompletableFuture.completedFuture(pong)
: askPong("Ping")
).thenCompose(x -> x);
Also, do not use the ...Async
methods unless you intend for the body of the supplied function to be executed asynchronously. So when you do something like
.handleAsync((x, t) -> {
if (t != null) {
return askPong("Ping");
} else {
return x;
})
You are asking for the if-then-else
to be run in a separate thread. Since askPong
returns a CompletableFuture
, there's probably no reason to run it asynchronously.
Solution 2:
Jeopardy question of the day:
thenApply
is tothenCompose
asexceptionally
is to what?
I know this was initially java-8, but, since java-12, the answer would be exceptionallyCompose
:
exceptionallyCompose[Async](Function<Throwable,? extends CompletionStage<T>> fn [, Executor executor])
Returns a new CompletionStage that, when this stage completes exceptionally, is composed using the results of the supplied function applied to this stage's exception.
As the JavaDoc indicates, the default implementation is:
return handle((r, ex) -> (ex == null)
? this
: fn.apply(ex))
.thenCompose(Function.identity());
That is, using handle()
to call the fallback, and thenCompose()
to unwrap the resulting nested CompletableFuture<CompletableFuture<T>>
– i.e., what you would have done in previous versions of Java (like in Misha’s answer), except you would have to replace this
with completedFuture(r)
.