onError<E extends Object> 方法

Future<T> onError<E extends Object>(
  1. FutureOr<T> handleError(
    1. E error,
    2. StackTrace stackTrace
    ),
  2. {bool test(
    1. E error
    )?}
)

处理此 Future 的错误。

捕获此 Future 完成的类型为 E 的错误。如果提供了 test,则仅捕获 test 返回 true 的类型为 E 的错误。如果 EObject,则根据提供的 test 可捕获所有错误。

如果错误被捕获,则返回的 Future 会通过调用带有错误和堆栈跟踪的 handleError 完成结果。此结果必须是此 Future 可能完成的相同类型的值。例如,如果此 Future 不能完成 null,则 handleError 也不能返回 null。示例

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

如果 handleError 抛出异常,则返回的 Future 会带有抛出的错误和堆栈跟踪完成,除非它再次抛出相同的错误对象,则被认为是一个“重新抛出”,并保留原始堆栈跟踪。这可以用作在 test 中跳过错误的替代方案。示例

// 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);

如果没有捕获错误,则返回的 Future 会与这个 Future 完成相同的最终结果、值或错误。

此方法实际上是 Future.catchError 的更精确类型版本。它使捕获特定错误类型变得容易,并且需要正确类型化的错误处理函数,而不是仅仅 Function。因此,错误处理器必须接受堆栈跟踪参数。

实现

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);
}