from<T extends Object?, S extends T?> static method

Future<AsyncPhase<T>> from<T extends Object?, S extends T?>(
  1. Future<T> func(), {
  2. S? fallbackData,
  3. void onComplete(
    1. T
    )?,
  4. void onError(
    1. S?,
    2. Object,
    3. StackTrace
    )?,
})

A method that runs an asynchronous function and returns either AsyncComplete with the function result as data or AsyncError with the error information, depending on whether or not the function completed successfully.

If the asynchronous function resulted in an error, the fallbackData value is used as the data of AsyncError.

The onComplete and onError callbacks are called when the asynchronous operation completes successfully or fails, respectively. The onError callback may be especially useful for logging purposes. However, note that errors occurring in those callbacks are not automatically handled.

Implementation

static Future<AsyncPhase<T>> from<T extends Object?, S extends T?>(
  Future<T> Function() func, {
  // `S` is a subtype of `T?`, but this parameter must not be of
  // type `T?`, in which case this method returns an `AsyncPhase<T?>`
  // in stead of `AsyncPhase<T>` if `null` is passed in.
  S? fallbackData,
  void Function(T)? onComplete,
  void Function(S?, Object, StackTrace)? onError,
}) async {
  AsyncPhase<T> phase;
  try {
    final data = await func();
    phase = AsyncComplete(data);
  }
  // ignore: avoid_catches_without_on_clauses
  catch (e, s) {
    phase = AsyncError(data: fallbackData, error: e, stackTrace: s);
  }

  if (phase case AsyncError(:final error, :final stackTrace)) {
    onError?.call(fallbackData, error, stackTrace);
  } else if (phase case AsyncComplete(:final data)) {
    onComplete?.call(data);
  }
  return phase;
}