runZonedGuarded<R> function Null safety

  1. @Since("2.8")
R? runZonedGuarded <R>(
  1. R body(
      ),
    1. void onError(
      1. Object error,
      2. StackTrace stack
      ),
    2. {Map<Object?, Object?>? zoneValues,
    3. ZoneSpecification? zoneSpecification}
    )

    Runs body in its own error zone.

    Creates a new zone using Zone.fork based on zoneSpecification and zoneValues, then runs body in that zone and returns the result.

    The onError function is used both to handle asynchronous errors by overriding ZoneSpecification.handleUncaughtError in zoneSpecification, if any, and to handle errors thrown synchronously by the call to body.

    If an error occurs synchronously in body, then throwing in the onError handler makes the call to runZonedGuarded throw that error, and otherwise the call to runZonedGuarded returns null.

    The zone will always be an error-zone.

    Errors will never cross error-zone boundaries by themselves. Errors that try to cross error-zone boundaries are considered uncaught in their originating error zone.

    var future = Future.value(499);
    runZonedGuarded(() {
      var future2 = future.then((_) { throw "error in first error-zone"; });
      runZonedGuarded(() {
        var future3 = future2.catchError((e) { print("Never reached!"); });
      }, (e, s) { print("unused error handler"); });
    }, (e, s) { print("catches error of first error-zone."); });
    

    Example:

    runZonedGuarded(() {
      new Future(() { throw "asynchronous error"; });
    }, (e, s) => print(e));  // Will print "asynchronous error".
    

    It is possible to manually pass an error from one error zone to another by re-throwing it in the new zone. If onError throws, that error will occur in the original zone where runZoned was called.

    Implementation

    @Since("2.8")
    R? runZonedGuarded<R>(R body(), void onError(Object error, StackTrace stack),
        {Map<Object?, Object?>? zoneValues, ZoneSpecification? zoneSpecification}) {
      ArgumentError.checkNotNull(body, "body");
      ArgumentError.checkNotNull(onError, "onError");
      _Zone parentZone = Zone._current;
      HandleUncaughtErrorHandler errorHandler = (Zone self, ZoneDelegate parent,
          Zone zone, Object error, StackTrace stackTrace) {
        try {
          parentZone.runBinary(onError, error, stackTrace);
        } catch (e, s) {
          if (identical(e, error)) {
            parent.handleUncaughtError(zone, error, stackTrace);
          } else {
            parent.handleUncaughtError(zone, e, s);
          }
        }
      };
      if (zoneSpecification == null) {
        zoneSpecification =
            new ZoneSpecification(handleUncaughtError: errorHandler);
      } else {
        zoneSpecification = ZoneSpecification.from(zoneSpecification,
            handleUncaughtError: errorHandler);
      }
      try {
        return _runZoned<R>(body, zoneValues, zoneSpecification);
      } catch (error, stackTrace) {
        onError(error, stackTrace);
      }
      return null;
    }