Why thenCombine result doesn't complete exceptionally if returning a failed stage?

963 Views Asked by At

The following code snippet, which invokes thenCombine, does not set an exception at whenComplete (it prints No exception):

    CompletableFuture.completedFuture(true)
    .thenCombine(CompletableFuture.completedFuture(true),
        (x,y) -> {
        return CompletableFuture.failedStage(new RuntimeException());
    })
    .whenComplete( (myVal, myEx) -> {
      if (myEx == null) {
         System.out.println("No exception");
      } else {
         System.out.println("There was an exception");
      }
    });

However, the similar code below, which invokes thenCompose, does set an exception:

    CompletableFuture.completedFuture(true)
    .thenCompose(
        x -> {
          return CompletableFuture.failedStage(new RuntimeException());
        })
    .whenComplete( (myVal, myEx) -> {
      if (myEx == null) {
        System.out.println("No exception");
      } else {
        System.out.println("There was an exception");
      }
    });

Why is thenCombine returning a normally-completed CompletionStage when its BiFunction is actually returning a failed stage?

1

There are 1 best solutions below

0
akuzminykh On BEST ANSWER

In your first example CompletableFuture.failedStage(new RuntimeException()) is the result. The CompletableFuture returned by thenCombine is completed with CompletableFuture.failedStage(new RuntimeException()).

It gets clearer when you don't chain the calls:

CompletableFuture<Boolean> first = CompletableFuture.completedFuture(true);
CompletableFuture<Boolean> second = CompletableFuture.completedFuture(true);
        
CompletableFuture<CompletionStage<?>> yourQuestion =
        first.thenCombine(second, (x, y) ->
                CompletableFuture.failedStage(new RuntimeException()));

For your second example you need to read the documentation of thenCompose carefully:

Returns a new CompletionStage that is completed with the same value as the CompletionStage returned by the given function.

In the function for thenCompose you return a failed CompletableFuture and its result is used as the result for the CompletableFuture returned by thenCompose: a RuntimeException.