web-dev-qa-db-ja.com

CompletableFutureの個別の例外処理

APIのコンシューマーが例外を処理する必要がないようにしたいと思います。または、もっと明確に、例外が常にログに記録されるようにしたいのですが、成功を処理する方法を知っているのはコンシューマーだけです。クライアントが必要に応じて例外も処理できるようにしたいのですが、クライアントに返すことができる有効なFileがありません。

注: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のことはよくわかりません。 exceptionまたはhandleを使用しますか?元の未来を返すのですか、それとも彼らが返す未来を返すのですか?

9
xenoterracide

CompletableFutureの結果に影響を与えたくないと仮定すると、 _CompletableFuture::whenComplete_ を使用する必要があります。

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

これで、APIのコンシューマーがfuture.get()を呼び出そうとすると、例外が発生しますが、必ずしもそれを使用して何もする必要はありません。


ただし、消費者に例外を知らないようにしたい場合(nullが失敗したときにfileDownloadを返す)、 _CompletableFuture::handle_ または-のいずれかを使用できます。 _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;
});
_
14
Jeffrey