code: public static <T, U> CompletableFuture<U> thenHandleCompose(CompletionStage<T> completionStage,
                                                                BiFunction<? super T, Throwable, ? extends CompletionStage<U>> fn) {
      return completionStage.handle((success, throwable) -> new SuccessOrThrowable<>(success, throwable))
          .thenCompose(pair ->
              fn.apply(pair.item, pair.ex)
          ).toCompletableFuture();
    }
docs: Useful for composing an async call in response to exceptional cases.
  For example:
  {@code
  return thenHandleCompose(myFuture, (success, th) -> {
  if (th != null) {
  return newCompletableFuture();
  } else {
  return CompletableFuture.completedFuture(success);
  }
  });
  }