Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java CompletableFuture handle versus whenComplete: recovery is explicit

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

CompletableFuture.whenComplete observes an outcome, while handle can produce a replacement value after success or failure.

Logging does not repair the stage

The failed lookup is observed by whenComplete, which prints the exception type. Joining that observed stage still fails. handle returns a fallback review state, so its dependent stage succeeds. These synchronous callbacks run as the source completes in this fixture; no executor is involved.

A fallback can conceal a real incident. Keep the original failure in telemetry and define when fallback is acceptable. allOf makes a separate batch-wide decision.

Avoid blocking inside callbacks

Callbacks can execute on a completion thread. A remote retry or long blocking operation inside handle can delay other work. Use a deliberately owned executor for expensive asynchronous stages and define its shutdown path.

Working program

Java
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
public class ReceiptRecoveryStage {
    public static void main(String[] args) {
        CompletableFuture<String> lookup = new CompletableFuture<>();
        CompletableFuture<String> observed = lookup.whenComplete((value, failure) ->
            System.out.println("observed=" + failure.getClass().getSimpleName()));
        CompletableFuture<String> recovered = lookup.handle((value, failure) ->
            failure == null ? value : "manual review");
        lookup.completeExceptionally(new IllegalArgumentException("unknown receipt"));
        try { observed.join(); }
        catch (CompletionException failure) {
            System.out.println("still=" + failure.getCause().getClass().getSimpleName());
        }
        System.out.println("fallback=" + recovered.join());
    }
}

Output

Output
observed=IllegalArgumentException
still=IllegalArgumentException
fallback=manual review

Costs and boundaries

This fixture checks stage outcomes but does not measure callback scheduling, retry traffic, or remote-service behavior. A fallback is an application policy, not an automatic fix for the upstream failure.

Common Mistakes

  • Do not expect whenComplete to consume the original failure.
  • Do not return a generic success fallback for every exception without a policy.
  • Do not block an uncontrolled completion thread with remote work.

Read next

Java CompletableFuture: composition, failures and executor ownership, Java CompletableFuture.allOf: completion barrier, not typed results, Java ExecutorService: bounded admission and shutdown.

java
completablefuture-handle-observe
Storage details