Functional Java - the interaction between ifComplete and exclusively

In this code:

doSomethingThatMightThrowAnException() .whenComplete((result, ex) -> doSomethingElse()}) .exceptionally(ex -> handleException(ex)); 

If there is an exception from doSomethingThatMightThrowAnException , doSomethingThatMightThrowAnException as doSomethingElse as doSomethingElse are handleException , or is it an exception that is consumed either whenComplete or exceptionally ?

EDIT:

doSomethingThatMightThrowAnException returns a CompletableFuture , which can completeExceptionally . This is the exception I'm talking about.

+14
java java-8 functional-programming
source share
3 answers

whenComplete documentation says:

Returns a new CompletionStage with the same result or exception as at this stage , which performs the specified action after completion of this stage.

(my accent)

This implies that the exception is not absorbed by this step, since it is assumed that it will have the same result or exception. However, you may be surprised at the fact that in subsequent stages an exception will be received from the previous stage, enclosed in a CompletionException , as described here , so this is not exactly the same exception:

 CompletableFuture<String> test=new CompletableFuture<>(); test.whenComplete((result, ex) -> System.out.println("stage 2: "+result+"\t"+ex)) .exceptionally(ex -> { System.out.println("stage 3: "+ex); return ""; }); test.completeExceptionally(new IOException()); 

will print:

 stage 2: null java.io.IOException stage 3: java.util.concurrent.CompletionException: java.io.IOException 

Note that you can always add multiple actions in one step instead of a chain:

 CompletableFuture<String> test=new CompletableFuture<>(); test.whenComplete((result, ex) -> System.out.println("stage 2a: "+result+"\t"+ex)); test.exceptionally(ex -> { System.out.println("stage 2b: "+ex); return ""; }); test.completeExceptionally(new IOException()); 
 stage 2b: java.io.IOException stage 2a: null java.io.IOException 

Of course, since now there is no relationship between 2a and 2b , there is no ordering between them, and in the case of asynchronous actions, they can be performed simultaneously.

+17
source share

exceptionally indicates:

Returns a new CompletableFuture that completes when this CompletableFuture completes, with the result of the given exception function that triggers this CompletableFuture completion when it completes exclusively; otherwise, if this CompletainFuture completes normally, then the returned CompletableFuture also ends normally with the same value. Note. More flexible versions of this functionality are available using the whenComplete and handle methods.

This is not so, IMHO is written in the clearest English, but I would say that this means that if an exception is thrown, only the exceptionally action will be activated. If no exception is thrown, only the normal action will be executed.

+2
source share

doSomethingThatMightThrowAnException() .whenComplete((result, ex) → doSomethingElse()}) with .whenComplete((result, ex) → doSomethingElse()}) and .exceptionally(ex → handleException(ex)); but if it throws an exception, it ends right there, since no object will be passed in the chain.

Remember that the exception will be doSomethingThatMightThrowAnException() caller, so if doSomethingThatMightThrowAnException() catches the internal exception, it will be doSomethingThatMightThrowAnException() . If this is your class, you should know if it really throws away, if not, check the documents for the libraries you use.

0
source share

All Articles