Dean Hiller Dean Hiller - 3 months ago 17
Java Question

How to invoke CompletableFuture callback while propagating result or error?

I was trying .exceptionally and .handle but those don't seem to work. In scala, you can call a method on the future with a closure that is just like a finally block(it runs on exception AND on success) AND it propogates the exception or success up the chain as-is.

I tried this...

CompletableFuture<Object> future = newFuture.handle((r, e) -> {
if(r != null)
return r;
else if(e != null)
return e;
else
return new RuntimeException("Asdf");
});

Assert.assertTrue(future.isCompletedExceptionally());


but that test fails as the future completely successfully with a result of exception(how weird).

Answer

Use CompletableFuture#whenComplete(BiConsumer). Its javadoc states

Returns a new CompletionStage with the same result or exception as this stage, that executes the given action when this stage completes.

When this stage is complete, the given action is invoked with the result (or null if none) and the exception (or null if none) of this stage as arguments. The returned stage is completed when the action returns. If the supplied action itself encounters an exception, then the returned stage exceptionally completes with this exception unless this stage also completed exceptionally.

In other words, it will be invoked regardless of success or failure and will propagate the initial future's state (unless the BiConsumer throws an exception).

CompletableFuture<String> future2 = newFuture.whenComplete((r, e) -> {
    // consume the result
});

If you needed to transform the result (in your example, you don't), then you could use handle and propagate things yourself.

Comments