guava/src/com/google/common/util/concurrent/Futures.java
@Beta
  @Partially.GwtIncompatible("AVAILABLE but requires exceptionType to be Throwable.class")
  public static <V, X extends Throwable> ListenableFuture<V> catching(
      ListenableFuture<? extends V> input,
      Class<X> exceptionType,
      Function<? super X, ? extends V> fallback,
      Executor executor) {
    return AbstractCatchingFuture.create(input, exceptionType, fallback, executor);
  }
@Beta
  @Partially.GwtIncompatible("AVAILABLE but requires exceptionType to be Throwable.class")
  public static <V, X extends Throwable> ListenableFuture<V> catching(
      ListenableFuture<? extends V> input,
      Class<X> exceptionType,
      Function<? super X, ? extends V> fallback,
      Executor executor) {
    return AbstractCatchingFuture.create(input, exceptionType, fallback, executor);
  }
@ Beta @ Partially . GwtIncompatible ( "AVAILABLE but requires exceptionType to be Throwable.class" ) public static < V , X extends Throwable > ListenableFuture < V > catching ( ListenableFuture < ? extends V > input , Class < X > exceptionType , Function < ? super X , ? extends V > fallback , Executor executor ) { return AbstractCatchingFuture . create ( input , exceptionType , fallback , executor ) ; }
Returns a {@code Future} whose result is taken from the given primary {@code input} or, if the
primary input 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
ListenableFuture<Integer> fetchCounterFuture = ...;

// Falling back to a zero counter in case an exception happens when
// processing the RPC to fetch counters.
ListenableFuture<Integer> faultTolerantFuture = Futures.catching(
fetchCounterFuture, 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 ListenableFuture#addListener ListenableFuture.addListener}
documentation. All its warnings about heavyweight listeners are also applicable to heavyweight
functions passed to this method.

@param input the primary input {@code Future}
@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 {@code 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 input.get()} or, if
{@code get()} throws a different kind of exception, that exception itself.
@param executor the executor that runs {@code fallback} if {@code input} fails
@since 19.0
Returns a { @code Future } whose result is taken from the given primary { @code input } or if the primary input 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 } .