Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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).

like image 215
Dean Hiller Avatar asked Aug 28 '16 01:08

Dean Hiller


People also ask

Can CompletableFuture throw exception?

The CompletableFuture. join() method is similar to the get method, but it throws an unchecked exception in case the Future does not complete normally.

How do you interrupt a Completable future?

As such, there's nothing you can do through CompletableFuture to interrupt any thread that may be running some task that will complete it. You'll have to write your own logic which tracks any Thread instances which acquire a reference to the CompletableFuture with the intention to complete it.

Is CompletableFuture get blocking?

It just provides a get() method which blocks until the result is available to the main thread. Ultimately, it restricts users from applying any further action on the result. You can create an asynchronous workflow with CompletableFuture. It allows chaining multiple APIs, sending ones to result to another.

Does completeExceptionally throw exception?

completeExceptionally() is an instance method of the CompletableFuture which is used to complete the future with the given exception. The subsequent calls to methods where we can retrieve results like get() and join() throwing the given exception.


1 Answers

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.

like image 141
Sotirios Delimanolis Avatar answered Oct 18 '22 10:10

Sotirios Delimanolis