android/guava/src/com/google/common/util/concurrent/FluentFuture.java
@Partially.GwtIncompatible("AVAILABLE but requires exceptionType to be Throwable.class")
  public final <X extends Throwable> FluentFuture<V> catching(
      Class<X> exceptionType, Function<? super X, ? extends V> fallback, Executor executor) {
    return (FluentFuture<V>) Futures.catching(this, exceptionType, fallback, executor);
  }
@Partially.GwtIncompatible("AVAILABLE but requires exceptionType to be Throwable.class")
  public final <X extends Throwable> FluentFuture<V> catching(
      Class<X> exceptionType, Function<? super X, ? extends V> fallback, Executor executor) {
    return (FluentFuture<V>) Futures.catching(this, exceptionType, fallback, executor);
  }
@ Partially . GwtIncompatible ( "AVAILABLE but requires exceptionType to be Throwable.class" ) public final < X extends Throwable > FluentFuture < V > catching ( Class < X > exceptionType , Function < ? super X , ? extends V > fallback , Executor executor ) { return ( FluentFuture < V > ) Futures . catching ( this , exceptionType , fallback , executor ) ; }
Returns a {@code Future} whose result is taken from this {@code Future} or, if this {@code
Future} fails with the given {@code exceptionType}, from the result provided by the {@code
fallback}. {@link Function#apply} is not invoked until the primary input has failed, so if the
primary input succeeds, it is never invoked. If, during the invocation of {@code fallback}, an
exception is thrown, this exception is used as the result of the output {@code Future}.

<p>Usage example:

<pre>{@code
// Falling back to a zero counter in case an exception happens when processing the RPC to fetch
// counters.
ListenableFuture<Integer> faultTolerantFuture =
fetchCounters().catching(FetchException.class, x -> 0, directExecutor());
}</pre>

<p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See
the discussion in the {@link #addListener} documentation. All its warnings about heavyweight
listeners are also applicable to heavyweight functions passed to this method.

<p>This method is similar to {@link java.util.concurrent.CompletableFuture#exceptionally}. It
can also serve some of the use cases of {@link java.util.concurrent.CompletableFuture#handle}
and {@link java.util.concurrent.CompletableFuture#handleAsync} when used along with {@link
#transform}.

@param exceptionType the exception type that triggers use of {@code fallback}. The exception
type is matched against the input's exception. "The input's exception" means the cause of
the {@link ExecutionException} thrown by {@code input.get()} or, if {@code get()} throws a
different kind of exception, that exception itself. To avoid hiding bugs and other
unrecoverable errors, callers should prefer more specific types, avoiding {@code
Throwable.class} in particular.
@param fallback the {@link Function} to be called if the input fails with the expected
exception type. The function's argument is the input's exception. "The input's exception"
means the cause of the {@link ExecutionException} thrown by {@code this.get()} or, if
{@code get()} throws a different kind of exception, that exception itself.
@param executor the executor that runs {@code fallback} if the input fails
Returns a { @code Future } whose result is taken from this { @code Future } or if this { @code Future } fails with the given { @code exceptionType } from the result provided by the { @code fallback } . { @link Function#apply } is not invoked until the primary input has failed so if the primary input succeeds it is never invoked . If during the invocation of { @code fallback } an exception is thrown this exception is used as the result of the output { @code Future } .