runCatching<R> method

  1. @visibleForTesting
  2. @protected
FutureOr<R?> runCatching<R>(
  1. FutureOr<R?> block(), {
  2. FutureOr<R?> onSuccess(
    1. R data
    )?,
  3. FutureOr<R?> onFailure(
    1. Object e,
    2. StackTrace s
    )?,
  4. @Deprecated('removed') bool ignoreSkipError = true,
  5. int slowlyMs = 0,
  6. Object? debounceTag,
  7. Object? throttleTag,
  8. Object? mutexTag,
})

ignoreSkipError same as update((o)=>null) true: SkipError will not trigger onFailure when true ref skpIf/skpNull slowlyMs if set <=0 value, will ignore debounce/throttleTag debounceTag enable debounce throttleTag enable throttle mutexTag enable concurrency lock (Exhaustive behavior)

Implementation

@visibleForTesting
@protected
FutureOr<R?> runCatching<R>(
  FutureOr<R?> Function() block, {
  FutureOr<R?> Function(R data)? onSuccess,
  FutureOr<R?> Function(Object e, StackTrace s)? onFailure,
  @Deprecated('removed') bool ignoreSkipError = true,
  int slowlyMs = 0,
  Object? debounceTag,
  Object? throttleTag,
  Object? mutexTag,
}) {
  FutureOr<R?> exec() {
    FutureOr<R?> onCatchError(Object e, [StackTrace? s]) {
      return (e is SkipError)
          ? null
          : onFailure?.call(e, s ?? StackTrace.current);
    }

    try {
      final rst = block();
      if (rst == null) return null;

      if (rst is Future<R?>) {
        return rst
            .then(
              (e) =>
                  e == null
                      ? null
                      : (onSuccess == null ? e : onSuccess.call(e)),
            )
            .catchError(onCatchError);
      } else if (rst is Future<R>) {
        return rst
            .then((e) => (onSuccess ?? (r) => r).call(e))
            .catchError(onCatchError);
      } else if (rst is Future) {
        // for other Future types (e.g. Future<dynamic>)
        return rst
            .then(
              (e) =>
                  e == null
                      ? null
                      : (onSuccess == null ? e as R : onSuccess.call(e as R)),
            )
            .catchError(onCatchError);
      }

      if (rst is R) return (onSuccess ?? (r) => r).call(rst);

      throw SkipError(
        'Unknown block result type [${rst.runtimeType}]; result [$rst];\n'
        'Please create new issues (https://github.com/Hu-Wentao/flowr/issues/new)',
      );
    } catch (e, s) {
      return onCatchError(e, s);
    }
  }

  if (mutexTag != null) return mutex<R?>(mutexTag, exec);

  if (slowlyMs > 0) {
    if (debounceTag != null) {
      return debounce<R?>(
        debounceTag,
        Duration(milliseconds: slowlyMs),
        exec,
      );
    }
    if (throttleTag != null) {
      return throttle<R?>(
        throttleTag,
        Duration(milliseconds: slowlyMs),
        exec,
      );
    }
  }

  return exec();
}