package com.millross.blog.async;

import org.junit.Test;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.atomic.AtomicReference;

/**
 *
 */
public class ExceptionalThenComposeTest extends CompletableFutureTestBase {


    @Test(expected = IntentionalException.class)
    public void exceptionCallingThenApplyAsSeenFromNextStage() throws Throwable {
        final AtomicReference<Throwable> thrownException = new AtomicReference<>(null);
        final CompletableFuture<Object> future = CompletableFuture.supplyAsync(delayedValueSupplier(1), executor)
                .thenCompose(i -> {
                    throw new IntentionalException();
                })
                .whenComplete((v, t) -> {
                    if (t != null) {
                        thrownException.set(t);
                    }
                });
        try {
            future.join();
        } catch (CompletionException ex) {
            throw (Optional.ofNullable(thrownException.get().getCause()).orElse(new RuntimeException("No thrown exception")));
        }
    }

}

@@ -319,99 +319,839 @@
  %7B%0A%0A
-%0A    @Test(expected = IntentionalException.class)%0A    public void exceptionCallingThenApply
+    /**%0A     * Note that while we throw an IntentionalException, get() causes it to be wrapped in an ExecutionException, in%0A     * effect, get acts as a subsequent completion stage from the point of view of exception propagation.%0A     * @throws Exception%0A     */%0A    @Test(expected = IntentionalException.class)%0A    public void exceptionCallingThenCompose() throws Throwable %7B%0A        final CompletableFuture%3CInteger%3E future = CompletableFuture.supplyAsync(delayedValueSupplier(1), executor)%0A                .thenCompose(i -%3E %7B%0A                    throw new IntentionalException();%0A                %7D);%0A%0A        try %7B%0A            future.join();%0A        %7D catch (CompletionException ex) %7B%0A            throw ex.getCause();%0A        %7D%0A%0A    %7D%0A%0A    @Test(expected = IntentionalException.class)%0A    public void exceptionCallingThenComposer
 AsSe

Correct thenCompose demo