2016-05-04 40 views
3

我意識到我希望API的使用者不必處理異常。或者更清楚地說,我想確保總是記錄異常,但只有消費者纔會知道如何處理成功。我希望客戶能夠處理異常,如果他們想要的話,我可以返回給他們沒有有效的FileCompletableFuture的分離異常處理

注:FileDownloadSupplier<File>

@Override 
public CompletableFuture<File> processDownload(final FileDownload fileDownload) { 
    Objects.requireNonNull(fileDownload); 
    fileDownload.setDirectory(getTmpDirectoryPath()); 
    CompletableFuture<File> future = CompletableFuture.supplyAsync(fileDownload, executorService); 
    future... throwable -> { 
     if (throwable != null) { 
      logError(throwable); 
     } 
     ... 
     return null; // client won't receive file. 
    }); 
    return future; 

} 

我真的不明白的東西CompletionStage。我是否使用exceptionhandle?我是否會回報原來的未來或他們回報的未來?

+0

如果拋出異常,您希望未來的結果如何?消費者是否仍然會受到例外,還是希望他們對發生的事情一無所知? – Jeffrey

+0

@Jeffrey我希望他們能夠接受例外,如果他們願意,也可以自己處理。我不指望他們收到文件 – xenoterracide

回答

7

假設你不想影響你的CompletableFuture的結果,你會希望使用CompletableFuture::whenComplete

future = future.whenComplete((t, ex) -> { 
    if (ex != null) { 
    logException(ex); 
    } 
}); 

現在,當您的API的消費者試圖調用future.get(),他們將得到一個異常,但他們不一定需要對此做任何事情。


不過,如果你想保持你的消費者無知的異常(返回nullfileDownload失敗),您可以使用CompletableFuture::handleCompletableFuture::exceptionally

future = future.handle((t, ex) -> { 
    if (ex != null) { 
    logException(ex); 
    return null; 
    } else { 
    return t; 
    } 
}); 

future = future.exceptionally(ex -> { 
    logException(ex); 
    return null; 
}); 
+3

這很容易。消費者對異常的無知可以使用'future.thenAccept'來簡單鏈接。這裏的關鍵是,消費者在例外情況下永遠不會被調用,所以它不需要處理,也不會產生異常,也不會產生'null'值。底線是,不要使用'get()'... – Holger