runZoned<R> function

R runZoned<R>(
  1. R body(), {
  2. Map<Object?, Object?>? zoneValues,
  3. ZoneSpecification? zoneSpecification,
  4. @Deprecated("Use runZonedGuarded instead") Function? onError,
})

Runs body in its own zone.

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

Example use:

var secret = "arglebargle"; // Or a random generated string.
var result = runZoned(
    () async {
      await Future.delayed(Duration(seconds: 5), () {
        print("${Zone.current[#_secret]} glop glyf");
      });
    },
    zoneValues: {#_secret: secret},
    zoneSpecification:
        ZoneSpecification(print: (Zone self, parent, zone, String value) {
      if (value.contains(Zone.current[#_secret] as String)) {
        value = "--censored--";
      }
      parent.print(zone, value);
    }));
secret = ""; // Erase the evidence.
await result; // Wait for asynchronous computation to complete.

The new zone intercepts print and stores a value under the private symbol #_secret. The secret is available from the new Zone object, which is the Zone.current for the body, and is also the first, self, parameter to the print handler function.

If the ZoneSpecification.handleUncaughtError is set, or the deprecated onError callback is passed, the created zone will be an error zone. Asynchronous errors in futures never cross zone boundaries between zones with a different Zone.errorZone. A consequence of that behavior can be that a Future which completes as an error in the created zone will seem to never complete when used from a zone that belongs to a different error zone. Multiple attempts to use the future in a zone where the error is inaccessible will cause the error to be reported again in it's original error zone.

See runZonedGuarded in place of using the deprected onError argument. If onError is provided this function also tries to catch and handle synchronous errors from body, but may throw an error anyway returning null if the generic argument R is not nullable.

Implementation

R runZoned<R>(
  R body(), {
  Map<Object?, Object?>? zoneValues,
  ZoneSpecification? zoneSpecification,
  @Deprecated("Use runZonedGuarded instead") Function? onError,
}) {
  if (onError != null) {
    // TODO: Remove this when code have been migrated off using [onError].
    if (onError is! void Function(Object, StackTrace)) {
      if (onError is void Function(Object)) {
        var originalOnError = onError;
        onError = (Object error, StackTrace stack) => originalOnError(error);
      } else {
        throw ArgumentError.value(
          onError,
          "onError",
          "Must be Function(Object) or Function(Object, StackTrace)",
        );
      }
    }
    return runZonedGuarded(
          body,
          onError,
          zoneSpecification: zoneSpecification,
          zoneValues: zoneValues,
        )
        as R;
  }
  return _runZoned<R>(body, zoneValues, zoneSpecification);
}