CompletableFuture 的分离异常处理

Separated exception handling of a CompletableFuture

我意识到我希望 API 的消费者不必处理异常。或者更明确地说,我想确保始终记录异常,但只有消费者知道如何处理成功。我希望客户也能够处理异常,如果他们愿意的话,没有有效的 File 我可以 return 给他们。

注:FileDownload是一个Supplier<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 的东西。我使用 exception 还是 handle?我return原来的未来还是他们return的未来?

假设您不想影响 CompletableFuture 的结果,您需要使用 CompletableFuture::whenComplete:

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

现在,当您的 API 的消费者尝试调用 future.get() 时,他们会得到一个异常,但他们不一定需要对其执行任何操作。


但是,如果你想让你的消费者不知道异常(return nullfileDownload 失败时),你可以使用 CompletableFuture::handle or CompletableFuture::exceptionally:

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

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