Java 12 added new exception handling methods in CompletionStage . Also check out the existing API for exception handling in CompletionStage.
Async exception handling
Existing method to handle exception:
CompletionStage<T> exceptionally(Function<Throwable,? extends T> fn)
New methods to handle exception asynchronously:
CompletionStage<T> exceptionallyAsync(Function<Throwable,? extends T> fn)
CompletionStage<T> exceptionallyAsync(Function<Throwable,? extends T> fn, Executor executor)
Example
package com.logicbig.example;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Ex1ExceptionallyAsync {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
CompletableFuture.supplyAsync(() -> {
printThreadInfo("division task");
return 10 / 0;
}).exceptionallyAsync(exception -> {
printThreadInfo("exceptionally Async");
System.err.println("exception: " + exception);
return 1;
}, executor
).thenApply(input -> {
printThreadInfo("multiply task");
return input * 3;
}).thenAccept(System.out::println);
Thread.sleep(2000);//let the stages complete
executor.shutdown();
}
private static void printThreadInfo(String desc) {
System.out.printf("%s, Thread: %s%n", desc, Thread.currentThread().getName());
}
}
division task, Thread: ForkJoinPool.commonPool-worker-3
exceptionally Async, Thread: pool-1-thread-1
exception: java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
multiply task, Thread: pool-1-thread-1
3
As seen above, exceptionally stage is invoked in a new thread.
Using old exceptionally() method:
package com.logicbig.example;
import java.util.concurrent.CompletableFuture;
public class Ex2ExceptionallyAsync {
public static void main(String[] args) throws Exception {
CompletableFuture.supplyAsync(() -> {
printThreadInfo("division task");
return 10 / 0;
}).exceptionally(exception -> {
printThreadInfo("exceptionally Async");
System.err.println("exception: " + exception);
return 1;
}).thenApply(input -> {
printThreadInfo("multiply task");
return input * 3;
}).thenAccept(System.out::println);
Thread.sleep(2000);
}
private static void printThreadInfo(String desc) {
System.out.printf("%s, Thread: %s%n", desc, Thread.currentThread().getName());
}
}
division task, Thread: ForkJoinPool.commonPool-worker-3
exceptionally Async, Thread: ForkJoinPool.commonPool-worker-3
exception: java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
multiply task, Thread: ForkJoinPool.commonPool-worker-3
3
Composing Exceptionally
Each of the following new methods returns a new CompletionStage that, when this stage completes exceptionally, is composed using the results of the supplied function applied to this stage's exception. (Also check out existing API of Composing completion stages)
CompletionStage<T> exceptionallyCompose(Function<Throwable,? extends CompletionStage<T>> fn)
CompletionStage<T> exceptionallyComposeAsync(Function<Throwable,? extends CompletionStage<T>> fn)
CompletionStage<T> exceptionallyComposeAsync(Function<Throwable,? extends CompletionStage<T>> fn, Executor executor)
Example
package com.logicbig.example;
import java.util.concurrent.CompletableFuture;
public class Ex3ExceptionallyCompose {
public static void main(String[] args) {
CompletableFuture<Integer> completableFuture = CompletableFuture
.supplyAsync(() -> {
return 10 / 0;
});
CompletableFuture<Integer> completableFuture2 = CompletableFuture
.supplyAsync(() -> 1);
CompletableFuture<Integer> exceptionallyCompose = completableFuture
.exceptionallyCompose(throwable -> {
System.err.println("exception: " + throwable);
return completableFuture2;
});
exceptionallyCompose.thenApply(i -> i * 3)
.thenAccept(System.out::println);
}
}
exception: java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
3
Example ProjectDependencies and Technologies Used: |