class SafeFuture extends CompletableFuture<T> {

  @SuppressWarnings({"FutureReturnValueIgnored", "MissingOverride"})
  public SafeFuture<T> exceptionallyCompose(
      final Function<Throwable, ? extends CompletionStage<T>> errorHandler) {
    final SafeFuture<T> result = new SafeFuture<>();
    whenComplete(
        (value, error) -> {
          try {
            final CompletionStage<T> nextStep =
                error != null ? errorHandler.apply(error) : completedFuture(value);
            propagateResult(nextStep, result);
          } catch (final Throwable t) {
            result.completeExceptionally(t);
          }
        });
    return result;
  }

}