I don't see an obvious way to handle an exception with an asynchronous result.
For example, if I want to retry an async operation, I would expect something like this:
CompletionStage<String> cf = askPong("cause error").handleAsync((x, t) -> {
if (t != null) {
return askPong("Ping");
} else {
return x;
}
});
Where askPong asks an actor:
public CompletionStage<String> askPong(String message){
Future sFuture = ask(actorRef, message, 1000);
final CompletionStage<String> cs = toJava(sFuture);
return cs;
}
However handleAsync
doesn't do what you think it does - it runs the callbacks on another thread asynchronously. Returning a CompletionStage
here is not correct.
Jeopardy question of the day: thenApply
is to thenCompose
as exceptionally
is to what?
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.
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)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With