CompletableFuture inconsistent exception handling?!

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

CompletableFuture inconsistent exception handling?!

Christian Schudt
Hi,

I am new to this list, because I have a couple of questions with regards to CompletableFuture and CompletionStage.

I discovered inconsistent behavior with the exception handling of CompletableFuture. When using completeExceptionally and there is no other CompletionStage in between, then the Exception is not wrapped in CompletionException. Otherwise or when using supplyAsync, it is wrapped.

Is this a bug or a design decision?

The problem for API users is that they never know if they are dealing with a CompletionException or with another one, leading to code like this in the handle or whenComplete function:

Throwable realException = t instanceof CompletionException ? t.getCause() : t;

Thanks for answers!

—Christian

Here’s my test code:


CompletableFuture<String> completableFuture1 = new CompletableFuture<>();
completableFuture1.whenComplete((x, t) -> System.out.println("1: " + t));
completableFuture1.completeExceptionally(new RuntimeException("test"));

CompletableFuture<String> completableFuture2 = new CompletableFuture<>();
completableFuture2.thenApply(result -> null).whenComplete((x, t) -> System.out.println("2: " + t));
completableFuture2.completeExceptionally(new RuntimeException("test"));

CompletableFuture<String> completableFuture3 = CompletableFuture.supplyAsync(() -> {
    throw new RuntimeException("test");
});
completableFuture3.whenComplete((x, t) -> System.out.println("3: " + t));


It prints:

1: java.lang.RuntimeException: test
2: java.util.concurrent.CompletionException: java.lang.RuntimeException: test
3: java.util.concurrent.CompletionException: java.lang.RuntimeException: test
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: CompletableFuture inconsistent exception handling?!

Martin Buchholz-3
Hopefully Doug will answer authoritatively, but I'll try:

On Sun, Jun 28, 2015 at 1:14 PM, Christian Schudt <[hidden email]> wrote:
Hi,

I am new to this list, because I have a couple of questions with regards to CompletableFuture and CompletionStage.

I discovered inconsistent behavior with the exception handling of CompletableFuture. When using completeExceptionally and there is no other CompletionStage in between, then the Exception is not wrapped in CompletionException. Otherwise or when using supplyAsync, it is wrapped.

Is this a bug or a design decision?

Design decision.  I agree it's a confusing situation.
 
The problem for API users is that they never know if they are dealing with a CompletionException or with another one, leading to code like this in the handle or whenComplete function:

Throwable realException = t instanceof CompletionException ? t.getCause() : t;


It allows you (forces you to?) distinguish between futures explicitly completed vs. inherited from another source, where it will be wrapped.
 

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest