runZonedGuarded<R> function
- @Since("2.8")
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
.
If the zone specification has a handleUncaughtError
value or the onError
parameter is provided, the zone becomes 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 = new Future.value(499);
runZoned(() {
var future2 = future.then((_) { throw "error in first error-zone"; });
runZoned(() {
var future3 = future2.catchError((e) { print("Never reached!"); });
}, onError: (e, s) { print("unused error handler"); });
}, onError: (e, s) { print("catches error of first error-zone."); });
Example:
runZoned(() {
new Future(() { throw "asynchronous error"; });
}, onError: (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 zoneValues, ZoneSpecification zoneSpecification}) {
ArgumentError.checkNotNull(body, "body");
ArgumentError.checkNotNull(onError, "onError");
HandleUncaughtErrorHandler errorHandler = (Zone self, ZoneDelegate parent,
Zone zone, error, StackTrace stackTrace) {
try {
self.parent.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 = new ZoneSpecification.from(zoneSpecification,
handleUncaughtError: errorHandler);
}
try {
return _runZoned<R>(body, zoneValues, zoneSpecification);
} catch (error, stackTrace) {
onError(error, stackTrace);
}
return null;
}