Skip to content
Advertisement

Why does calling CompletableFuture::cancel cause an immediate CancellationException

I am trying to call cancel on CompletableFuture.

It seems from the docs:

If not already completed, completes this CompletableFuture with a CancellationException. Dependent CompletableFutures that have not already completed will also complete exceptionally, with a CompletionException caused by this CancellationException.

That it should complete them exceptionally which is what I was expecting but instead, it throws and immediate CancellationException.

Here is a sample code

JavaScript

With a repro : https://www.mycompiler.io/view/2v1ME4u

JavaScript

Line 7 is the f.cancel(true); line.

Advertisement

Answer

It doesn’t actually throw immediately.

Calling f.cancel(true) causes a CancellationException to be created, capturing the stack trace of the call to cancel. So the stack trace (which is printed because it’s unhandled) contains the line of the f.cancel(true); call.

But that exception isn’t actually thrown until f.join():

Returns the result value when complete, or throws an (unchecked) exception if completed exceptionally

Throws:

CancellationException – if the computation was cancelled

You can see this by putting in a few more print statements into your example code:

JavaScript

Output:

JavaScript
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement