description

# runZonedGuarded<R> function Null safety

1. @Since("2.8")

R? runZonedGuarded <R>(

1. R body(
   ),
2. void onError(
   1. Object error,
   2. StackTrace stack
   ),
3. {Map<Object?, Object?>? zoneValues,
4. 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;
    }