CompletableFuture.exceptionallyCompose replaces an exceptional outcome with a new CompletionStage, allowing recovery that itself finishes asynchronously.
Java exceptionallyCompose: recover with another asynchronous stage
Operational contract
A primary receipt lookup can fail into a secondary lookup supplied by the caller. The callback may receive a CompletionException wrapper, so classification should inspect causes under a deliberate policy. This sample only retries an unavailable primary; validation failures and cancellation remain failures. The secondary future is created only after failure. Java 17 is the declared baseline for this lesson, and the method is available there. A fallback also needs its own deadline and resource budget.
Failure case
A primary read fails with a transient depot-unavailable exception. The backup read begins. If the primary fails because the receipt ID is malformed, the original failure is preserved instead of issuing a pointless backup request.
Java code
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.function.Supplier;
public class ReceiptReplicaFallback {
public static class DepotUnavailable extends RuntimeException {
public DepotUnavailable(String message) { super(message); }
}
public static CompletableFuture<String> recover(
CompletableFuture<String> primary,
Supplier<CompletableFuture<String>> backup) {
Objects.requireNonNull(primary);
Objects.requireNonNull(backup);
return primary.exceptionallyCompose(failure -> {
Throwable cause = failure instanceof CompletionException && failure.getCause() != null
? failure.getCause() : failure;
if (!(cause instanceof DepotUnavailable))
return CompletableFuture.failedFuture(cause);
return Objects.requireNonNull(backup.get(), "Backup stage missing");
});
}
}Performance and ownership cost
Successful primary requests pay O(1) stage bookkeeping and no backup work. A qualifying failure incurs the secondary request's full latency and resource cost. A fallback that fans out repeatedly can amplify load during an outage.
Common Mistakes
- Do not route cancellation or invalid input to a backup automatically.
- Do not forget that a backup stage can fail or never complete.
- Do not implement unbounded recursive recovery during an outage.
