I am new to the world of CompletableFuture. I am trying to do some negative tests, in a way that will allow me to throw an exception intentionally. This exception will decide the PASS/FAIL.
Here's the code snippet:
protected CompletableFuture<Response> executeAsync(@NonNull Supplier<Response> call) {
return CompletableFuture
.supplyAsync(call::get)
.whenCompleteAsync((response, exception) -> {
if (exception == null) {
try {
Helper.throwIfNotExpected(clientProperties.getName(), response, null);
} catch (ServiceException e) {
throw new ServiceException(null,e.getMessage(),null);
}
} else {
log.error("Async API call failed.", exception);
}
});
}
This gives me an error saying unhandled exception in catch part. I looked up examples and documentation but could not find much information about Exception handling in supplyAsync/whenCompleteAsync. Thanks in advance.
CodePudding user response:
A good way to work around the shortcoming of CompletableFuture
regarding checked exceptions is to delegate to another CompletableFuture
instance. For your example it would look like something along the lines of
protected CompletableFuture<Response> executeAsync(Supplier<Response> call) {
CompletableFuture<Response> delegate = new CompletableFuture<>();
CompletableFuture
.supplyAsync(call)
.whenCompleteAsync((response, exception) -> {
if (exception == null) {
try {
Helper.throwIfNotExpected(clientProperties.getName(), response, null);
delegate.complete(response);
} catch (ServiceException e) {
delegate.completeExceptionally(new ServiceException(null,e.getMessage(),null));
}
} else {
log.error("Async API call failed.", exception);
delegate.completeExceptionally(exception);
}
});
return delegate;
}