description

# onError<E extends Object> method

Future<T> onError<E extends Object>(

1. FutureOr<T> handleError(
   1. E error,
   2. StackTrace stackTrace
   ), {
2. bool test(
   1. E error
   )?,

})

Handles errors on this future.

Catches errors of type `E` that this future complete with. If `test` is supplied, only catches errors of type `E` where `test` returns `true`. If `E` is Object, then all errors are potentially caught, depending only on a supplied `test`.

If the error is caught, the returned future completes with the result of calling `handleError` with the error and stack trace. This result must be a value of the same type that this future could otherwise complete with. For example, if this future cannot complete with `null`, then `handleError` also cannot return `null`. Example:

    Future<T> retryOperation<T>(Future<T> operation(), T onFailure()) =>
        operation().onError<RetryException>((e, s) {
          if (e.canRetry) {
            return retryOperation(operation, onFailure);
          }
          return onFailure();
        });

If `handleError` throws, the returned future completes with the thrown error and stack trace, except that if it throws the same error object again, then it is considered a "rethrow" and the original stack trace is retained. This can be used as an alternative to skipping the error in `test`. Example:

    // Unwraps an exceptions cause, if it has one.
    someFuture.onError<SomeException>((e, _) {
      throw e.cause ?? e;
    });
    // vs.
    someFuture.onError<SomeException>((e, _) {
      throw e.cause!;
    }, test: (e) => e.cause != null);

If the error is not caught, the returned future completes with the same result, value or error, as this future.

This method is effectively a more precisely typed version of Future.catchError. It makes it easy to catch specific error types, and requires a correctly typed error handler function, rather than just Function. Because of this, the error handlers must accept the stack trace argument.

## Implementation

    Future<T> onError<E extends Object>(
      FutureOr<T> handleError(E error, StackTrace stackTrace), {
      bool test(E error)?,
    }) {
      FutureOr<T> onError(Object error, StackTrace stackTrace) {
        if (error is! E || test != null && !test(error)) {
          // Counts as rethrow, preserves stack trace.
          throw error;
        }
        return handleError(error, stackTrace);
      }

      if (this is _Future<Object?>) {
        // Internal method working like `catchError`,
        // but allows specifying a different result future type.
        return unsafeCast<_Future<T>>(this)._safeOnError<T>(onError);
      }

      return this.then<T>((T value) => value, onError: onError);
    }