Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ignore a failed CompletableFuture call when multiple Async calls are made in Java?

I want to consume three REST service parallel calls in Java and my code is as below:

private CompletableFuture < EmployeesListResponse > makeAsyncCall(Request request) {
 return CompletableFuture.supplyAsync(
  () -> {
   try {
    LOGGER.warn("- - - - - Employees Service async call - - - - -");
    return serviceObj.findServiceImpl(request);
   } catch (Exception e) {
    LOGGER.warn("service async call failed...", e);
   }
   return null;
  }, asyncExecutor).handle((res, ex) -> {
  LOGGER.warn("Exceptionally...", ex.toString(), res.toString());
  return new EmployeesListResponse();
 });
}

CompletableFuture < EmployeesListResponse > asyncFirstCall = makeAsyncCall(request);
CompletableFuture < EmployeesListResponse > asyncSecondCall = makeAsyncCall(request);
CompletableFuture < EmployeesListResponse > asyncThirdCall = makeAsyncCall(request);

CompletableFuture.allOf(asyncFirstCall, asyncSecondCall, asyncThirdCall).join();

In the above code, I am making three calls and joining them using CompletableFuture.allOf().join(). This code is working perfectly fine when the service response is 200 OK for all the three calls.

If one call fails(500 Internal Server Error or 404 Not Found) and other two service calls are 200 OK, then the code is throwing exception and the entire API response is getting failed with an exception. In this case, i want to ignore one service call with exception and return success response from the other two calls.

How to handle to ignore an exception in this scenario ?

like image 296
Vamsi Avatar asked Oct 12 '25 06:10

Vamsi


1 Answers

So you're trying to wait for all 3 futures to complete before finishing, but the allOf future returns immediately when a single one fails. Instead you can explicitly wait on each:

List<CompletableFuture<String>> allFutures = Arrays.asList(asyncFirstCall, asyncSecondCall,
        asyncThirdCall);
// await completion of all futures
allFutures.forEach(future -> {
    try {
        future.join();
    } catch (CompletionException ex) {
        // handled below.
    }
});

if (allFutures.stream().filter(CompletableFuture::isCompletedExceptionally).count() > 2) {
    throw new RuntimeException("Multiple failures");
}

// else continue with your business logic...
like image 151
MikeFHay Avatar answered Oct 14 '25 21:10

MikeFHay