resolve method

FutureOr<V> resolve({
  1. bool throwError = true,
  2. FutureOr<V> onError(
    1. Object error,
    2. StackTrace stackTrace
    )?,
  3. V? onErrorValue,
})

Resolves the computation and returns its value (V) or a Future<V>.

  • If already resolved, returns the cached value or handles/rethrows the cached error.
  • If a resolution is in progress, returns the same in-flight Future.
  • When the computation completes (success or failure), onCompute is invoked with the resulting value or error.

Parameters:

  • throwError: When true (default), any error is rethrown with its original StackTrace. When false, errors are handled by onError or onErrorValue.

  • onError: Optional error handler invoked when an error occurs and throwError is false. Receives the error object and its StackTrace. Its return value is used as the resolved value.

  • onErrorValue: Fallback value (default null) returned when an error occurs, throwError is false, and onError is not provided.

Implementation

FutureOr<V> resolve({
  bool throwError = true,
  FutureOr<V> Function(Object error, StackTrace stackTrace)? onError,
  V? onErrorValue,
}) {
  var result = _result;
  if (result != null) {
    var error = result.error;
    if (error != null) {
      var stackTrace = result.stackTrace!;
      if (throwError) {
        Error.throwWithStackTrace(error, stackTrace);
      } else if (onError != null) {
        return onError(error, stackTrace);
      } else {
        return _castErrorValue(onErrorValue);
      }
    }
    return result.value as V;
  }

  var future = _future;
  if (future != null) {
    if (!throwError) {
      if (onError != null) {
        return future.catchError(onError);
      } else {
        return future.catchError((e, s) => _castErrorValue(onErrorValue));
      }
    }
    return future;
  }

  FutureOr<V> resolveError(Object e, StackTrace s) {
    _result = (value: null, error: e, stackTrace: s);
    _call = null;
    onCompute(null, e, s);

    if (!throwError) {
      if (onError != null) {
        return onError(e, s);
      } else {
        return _castErrorValue(onErrorValue);
      }
    } else {
      Error.throwWithStackTrace(e, s);
    }
  }

  final posCompute = this.posCompute;
  final FutureOr<V> call;

  try {
    var computer = _call ?? (throw StateError("Null `_call`"));
    call = computer();

    if (call is Future<V>) {
      future = _future = call;

      if (posCompute != null) {
        future = _future = future.then((v) {
          return posCompute(v, null, null);
        }, onError: (e, s) {
          return posCompute(null, e, s);
        });
      }

      return _resolveFuture(future, throwError, onError, onErrorValue);
    } else {
      var value = call;

      if (posCompute != null) {
        try {
          var value2 = posCompute(value, null, null);

          if (value2 is Future<V>) {
            future = _future = value2;
            return _resolveFuture(future, throwError, onError, onErrorValue);
          } else {
            value = value2;
          }
        } catch (e, s) {
          return resolveError(e, s);
        }
      }

      _result = (value: value, error: null, stackTrace: null);
      _call = null;
      onCompute(value, null, null);
      return value;
    }
  } catch (e, s) {
    return resolveError(e, s);
  }
}