Separated exception handling of a CompletableFuture
Assuming that you do not want to affect the result of your CompletableFuture
, you'll want to use CompletableFuture::whenComplete
:
future = future.whenComplete((t, ex) -> {
if (ex != null) {
logException(ex);
}
});
Now when the consumer of your API tries to call future.get()
, they will get an exception, but they don't necessarily need to do anything with it.
However, if you want to keep your consumer ignorant of the exception (return null
when the fileDownload
fails), you can use either CompletableFuture::handle
or CompletableFuture::exceptionally
:
future = future.handle((t, ex) -> {
if (ex != null) {
logException(ex);
return null;
} else {
return t;
}
});
or
future = future.exceptionally(ex -> {
logException(ex);
return null;
});
xenoterracide
Former Linux System Administrator, now full time Java Software Engineer.
Updated on July 24, 2022Comments
-
xenoterracide almost 2 years
I realize that I'd like the consumers of our API to not have to handle an exception. Or perhaps more clearly I'd like to ensure that the exception is always logged, but only the consumer will know how to handle success. I want the client to be able to handle the exception as well if they want, There is no valid
File
that I could return to them.Note:
FileDownload
is aSupplier<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; }
I don't really understand the
CompletionStage
stuff. Do I useexception
orhandle
? do I return the original future or the future they return?-
Jeffrey about 8 yearsWhat do you want the result of your future to be if an exception is thrown? Should the consumer still receive the exception, or do you want them to be ignorant of what happened?
-
xenoterracide about 8 years@Jeffrey I would expect them to receive the exception, handle it themselves as well if they want. I don't expect them to receive a File
-
-
Holger about 8 yearsIt’s much easier. A consumer being ignorant against exceptions can be simply chained using
future.thenAccept
. The key point here is that the consumer is never called in the exceptional case, so it doesn’t have to handle neither, an exception nor anull
value. The bottom line is, don’t useget()
…