Hi all, I just stumbled upon a strange behaviour and I'm not sure if it is intended this way or whether it's a bug. It is also possible I'm using the API incorrectly. Let me explain with an example:
``` var originalException = new Exception("foo"); CompletableFuture.failedFuture(originalException).exceptionally(e -> { assert originalException == e; return null; }); ``` This works as expected. However the following does not: ``` var originalException = new Exception("foo"); CompletableFuture.failedFuture(originalException).thenCompose(obj -> CompletableFuture.completedFuture(obj)).exceptionally(e -> { assert originalException == e; // FAIL! return null; }); ``` Note, that the "identity"-function passed to `thenCompose(...)` will not even be called, since the future is already in failed state. However CompletableFuture's implementation wraps the original exception into a new CompletionException. So the mere presence of a `thenCompose(...)` somewhere in the chain will change how to deal with exceptions further downstream. Neither do I find this side effect `thenCompose` documented, nor is it part of the contract of `exceptionally(...)` or `handle(...)` to only return CompletionExceptions. And don't get me started on `get()` and `join()`... Depending on the context of your code, you don't know whether or not there was a `thenCompose`, so you need to check for both, the expected exception as well as a CompletionException with its cause being the expected exception. So is this a bug? Or is this a thing that is not going to be changed, since other software already implemented workarounds for this behaviour? If so, should I move to 3rd party libs? Cheers! Sebastian