Search code examples
javaerror-handlingjava.util.concurrent

Forking exception handling in Java CompletableStage


I have not used Java in a million years and trying to figure out how to differentiate between different types of Exception in CompleteableStage.

Currently, I have something like below but it does not look too beautiful. Is there a more elegant way of achieving the same result?

Thanks!

public CompletableFuture<DoStuffResponse> doStuff(
      DoStuffRequest request) {

    return stuffClient
        .doClientStuff(request)
        .thenApply(
            response -> {
              blah
              timer.stop();
              return response;
            })
        .exceptionally(
            e -> {
              if (e.getCause() instanceof ValidationException)) {
            
                     throw new CustomException("Validation failed doing stuff " + e.getMessage(), e);
              } else            
                  throw new OtherCustomException("Failed doing stuff " + e.getMessage(), e);
              }   
        .toCompletableFuture();
  }

public interface StufClient {

     CompletionStage<DoStuffResponse> doClientStuff(DoStuffRequest request); 

It works but it does not look very nice


Solution

  • If you are using Java 17+, you can use switch expression and pattern matching for instanceof

    .exceptionally(e -> {
        throw switch (e.getCause()) {
            case ValidationException ve -> new CustomException("Validation failed doing stuff: " + ve.id, ve);
            case CustomServerException cse -> new CustomException("Custom server exception: customField=" + cse.customField, cse);
            default -> new OtherCustomException("Failed doing stuff: " + e.getMessage(), e);
        };
    })