capture<T> method Null safety

T capture <T>(
  1. T callback(
    1. {void onError(
      1. Object error,
      2. Chain
    2. bool when: true,
    3. bool errorZone: true}

    If when is true, runs callback in a Zone in which the current stack chain is tracked and automatically associated with (most) errors.

    If when is false, this does not track stack chains. Instead, it's identical to runZoned, except that it wraps any errors in new Chain.forTrace—which will only wrap the trace unless there's a different Chain.capture active. This makes it easy for the caller to only capture stack chains in debug mode or during development.

    If onError is passed, any error in the zone that would otherwise go unhandled is passed to it, along with the Chain associated with that error. Note that if callback produces multiple unhandled errors, onError may be called more than once. If onError isn't passed, the parent Zone's unhandledErrorHandler will be called with the error and its chain.

    If errorZone is true, the zone this creates will be an error zone, even if onError isn't passed. This means that any errors that would cross the zone boundary are considered unhandled. If errorZone is false, onError must be null.

    If callback returns a value, it will be returned by capture as well.


    static T capture<T>(T Function() callback,
        {void Function(Object error, Chain)? onError,
        bool when = true,
        bool errorZone = true}) {
      if (!errorZone && onError != null) {
        throw ArgumentError.value(
            onError, 'onError', 'must be null if errorZone is false');
      if (!when) {
        void Function(Object, StackTrace)? newOnError;
        if (onError != null) {
          void wrappedOnError(Object error, StackTrace? stackTrace) {
                stackTrace == null
                    ? Chain.current()
                    : Chain.forTrace(stackTrace));
          newOnError = wrappedOnError;
        return runZoned(callback, onError: newOnError);
      var spec = StackZoneSpecification(onError, errorZone: errorZone);
      return runZoned(() {
        try {
          return callback();
        } on Object catch (error, stackTrace) {
          // TODO(nweiz): Don't special-case this when issue 19566 is fixed.
          Zone.current.handleUncaughtError(error, stackTrace);
          // If the expected return type of capture() is not nullable, this will
          // throw a cast exception. But the only other alternative is to throw
          // some other exception. Casting null to T at least lets existing uses
          // where T is a nullable type continue to work.
          return null as T;
          zoneSpecification: spec.toSpec(),
          zoneValues: {_specKey: spec, StackZoneSpecification.disableKey: false});