私はCompletableFutureチェーンで遊んでいて、予期せぬ動作(私にとっては少なくとも)の状況に遭遇しました:例外的なCompletableFutureが.thenCompose()
呼び出しで渡された場合、結果のCompletableFutureは元の例外がラップされて終了しますCompletionException
にあります。たとえばなしで理解するのは難しいかもしれ:もちろん希望するCompletableFutureの動作を強制する
public static <T> CompletableFuture<T> exceptional(Throwable error) {
CompletableFuture<T> future = new CompletableFuture<>();
future.completeExceptionally(error);
return future;
}
public static void main(String[] args) {
CompletableFuture<Void> exceptional = exceptional(new RuntimeException());
exceptional
.handle((result, throwable) -> {
System.out.println(throwable);
// java.lang.RuntimeException
System.out.println(throwable.getCause());
// null
return null;
});
CompletableFuture
.completedFuture(null)
.thenCompose(v -> exceptional)
.handle((result, throwable) -> {
System.out.println(throwable);
// java.util.concurrent.CompletionException: java.lang.RuntimeException
System.out.println(throwable.getCause());
// java.lang.RuntimeException
return null;
});
}
私は関係なく、チェーン内の前か後だったどのように多くの変換同じRuntimeException
に対処しないように期待していました。私は2つの質問があります:
- これは予想される動作ですか?
- 手動アンラッピングを除いて、元の例外を引き継ぐためのオプションがありますか?