Is it possible to fail a CompletableFuture based on a condition? In other words, convert a success result into an exceptional result? Is there an API for it?
At the moment, I am doing the following, but it feels awkward and convoluted:
CompletableFuture<CustomClass> inputFuture = doWork();
CompletableFuture<CustomClass> outputFuture = new CompletableFuture<>();
inputFuture.whenComplete((result, ex) -> {
if (ex != null) {
outputFuture.completeExceptionally(ex);
} else {
Outcome outcome = verify(result);
if (outcome.isNegativeResult()) {
outputFuture.completeExceptionally(outcome.getException());
} else {
outputFuture.complete(result);
}
}
});
return outputFuture;
Not very expressive. I see there is thenCompose
which automatically handles the exceptional condition and reduces it to:
CompletableFuture<CustomClass> inputFuture = doWork();
return inputFuture.thenCompose(result -> {
Outcome outcome = verify(result);
if (outcome.isNegativeResult()) {
return CompletableFuture.failedFuture(outcome.getException());
} else {
return CompletableFuture.completedFuture(result);
}
});
It's the best with which I could come up, but it still feels a bit clumsy (temporary throw-away futures are newed up, only to transport the value).
Is there a shorter, more idiomatic or more concise way of expressing this using the CompletableFuture API? How does each solution compare when it comes to performance (or is the difference mostly negligible?)
PS. I don't know the type of exception to be propagated beforehand, but let's assume it is a checked exception and it cannot be changed to an unchecked one. Wrapping in an unchecked exception isn't an option either, because it will change the direct type of the exception as seen by consumers.