簡體   English   中英

如何從CompletableFuture拋出自定義異常?

[英]How to throw a custom exception from CompletableFuture?

問題:如何直接從.exceptionally()拋出自定義異常?

List<CompletableFuture<Object>> futures =
    tasks.stream()
        .map(task -> CompletableFuture.supplyAsync(() -> businessLogic(task))
        .exceptionally(ex -> {
                if (ex instanceof BusinessException) return null;

                //TODO how to throw a custom exception here??
                throw new BadRequestException("at least one async task had an exception");
        }))
        .collect(Collectors.toList());

try {
    List<Object> results = futures.stream()
        .map(CompletableFuture::join)
        .collect(Collectors.toList());
} catch (CompletionException e) {
        if (e.getCause() instanceof RuntimeException) {
              throw (RuntimeException) e.getCause();
        }
        throw new RuntimeException(e.getCause());
}

問題:我總是得到一個CompletionExceptionex.getCause()BadRequestException instanceof。

這有可能嗎?

正如Didier L所說,函數拋出的異常(或者通常是完成 CompletableFuture 異常 )總是包含在CompletionException (除非它們已經是CompletionExceptionCancellationException )。

但請注意,甚至在嘗試通過exceptionally轉換異常時,您的代碼變得更加簡單:

List<CompletableFuture<Object>> futures =
    tasks.stream()
        .map(task -> CompletableFuture.supplyAsync(() -> businessLogic(task)))
        .collect(Collectors.toList());
try {
    List<Object> results = futures.stream()
        .map(CompletableFuture::join)
        .collect(Collectors.toList());
} catch (CompletionException e) {
    throw e.getCause() instanceof BusinessException?
        new BadRequestException("at least one async task had an exception"): e;
}

要么

… catch (CompletionException e) {
    throw e.getCause() instanceof BusinessException?
        new BadRequestException("at least one async task had an exception"):
        e.getCause() instanceof BusinessException? (RuntimeException)e.getCause(): e;
}

由於exceptionally的主要目的是將異常轉換為非異常結果值,因此使用它將異常轉換為另一個拋出的異常並不是最合適的,它還需要一個instanceof 因此,在catch子句中執行此轉換將使您免於另一個轉換步驟。

這是不可能的。 join()Javadoc明確指出:

完成后返回結果值,如果異常完成則拋出(未經檢查的)異常。 為了更好地符合常用函數形式的使用, 如果完成此CompletableFuture所涉及的計算引發異常,則此方法將拋出(未經檢查的) CompletionException ,並將基礎異常作為其原因。

(重點是我的)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM