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,则仅捕获类型为 Etest 返回 true 的错误。如果 EObject,则所有错误都有可能被捕获,这仅取决于提供的 test。toString()

如果错误被捕获,返回的 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);
}