New implementation of runZoned.

A combination of `runZoned` and `runZonedGuarded` where only the latter allows an `onError` parameter,
and only that has a nullable return type.

Retains the `onError` parameter on `runZoned` for now because it's too breaking to remove it until packages have been migrated off of it.
It will be removed in a follow-up CL.

Change-Id: If0e86c8d14e13fa089c66f4af975aeacb2616cf6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/137302
Reviewed-by: Jake Macdonald <jakemac@google.com>
Reviewed-by: Nate Bosch <nbosch@google.com>
This commit is contained in:
Lasse R.H. Nielsen 2020-03-25 00:24:33 +00:00 committed by Leaf Petersen
parent 289c4d5990
commit 8760283247
44 changed files with 315 additions and 252 deletions

View file

@ -13,6 +13,13 @@
stack trace rather than propagate a `null` value.
Error handling functions need no longer be prepared for `null` stack traces.
* **Breaking change**: [#40681](https://github.com/dart-lang/sdk/issues/40681)
The `runZoned` function is split into two functions: `runZoned` and
`runZonedGuarded`, where the latter has a required `onError` parameter,
and the former has none.
This prepares the functions for Null Safety where the two functions will
differ in the nullability of their return types.
#### `dart:core`
* Adds `StackTrace.empty` constant which is the stack trace used as default
@ -137,6 +144,18 @@ used (see Issue [39627][]).
address in byte format for Internet addresses or raw file path for Unix
domain addresses.
* **Breaking change** [#40681](https://github.com/dart-lang/sdk/issues/40681)
The static method `runZoned` and `runWithHttpOverrides` on `HttpOverrides`
no longer accept `zoneSpecification` and `onError` parameters.
Use the `runZoned` or `runZonedGuarded` functions from `dart:async`
directly if needing to specify those.
* **Breaking change** [#40681](https://github.com/dart-lang/sdk/issues/40681)
The static method `runZoned` and `runWithIOOverrides` on `IOOverrides`
no longer accept `zoneSpecification` and `onError` parameters.
Use the `runZoned` or `runZonedGuarded` functions from `dart:async`
directly if needing to specify those.
#### `dart:mirrors`
* Added `MirrorSystem.neverType`.
@ -188,7 +207,7 @@ additional details see the [announcement].
Use of this library on the web has been unsupported and prevented by the Dart
build systems since Dart v2.0.0. All known exception cases have been cleaned
up. This change makes DDC and dart2js now behave consistently.
The library can still be imported on web apps, but all APIs throw. In a future
breaking change release, imports to this library will likely become a
compile-time error.

View file

@ -312,7 +312,7 @@ class AnalysisServer extends AbstractAnalysisServer {
/// Handle a [request] that was read from the communication channel.
void handleRequest(Request request) {
performance.logRequestTiming(request.clientRequestTime);
runZoned(() {
runZonedGuarded(() {
ServerPerformanceStatistics.serverRequests.makeCurrentWhile(() {
int count = handlers.length;
for (int i = 0; i < count; i++) {
@ -341,7 +341,7 @@ class AnalysisServer extends AbstractAnalysisServer {
}
channel.sendResponse(Response.unknownRequest(request));
});
}, onError: (exception, stackTrace) {
}, (exception, stackTrace) {
AnalysisEngine.instance.instrumentationService.logException(
FatalException('Failed to handle request: ${request.method}',
exception, stackTrace));

View file

@ -144,9 +144,9 @@ class ByteStreamServerChannel implements ServerCommunicationChannel {
/// Send the string [s] to [_output] followed by a newline.
void _outputLine(String s) {
runZoned(() {
runZonedGuarded(() {
_output.writeln(s);
}, onError: (e) {
}, (e, s) {
close();
});
}

View file

@ -217,7 +217,7 @@ class CompletionDomainHandler extends AbstractRequestHandler {
);
}
return runZoned(() {
return runZonedGuarded(() {
String requestName = request.method;
if (requestName == COMPLETION_REQUEST_GET_SUGGESTION_DETAILS) {
@ -233,7 +233,7 @@ class CompletionDomainHandler extends AbstractRequestHandler {
return setSubscriptions(request);
}
return null;
}, onError: (exception, stackTrace) {
}, (exception, stackTrace) {
AnalysisEngine.instance.instrumentationService.logException(
CaughtException.withMessage(
'Failed to handle completion domain request: ${request.method}',

View file

@ -942,7 +942,7 @@ class _RefactoringManager {
?.sendEvent('refactor', params.kind.name.toLowerCase());
}
runZoned(() async {
runZonedGuarded(() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
await _init(params.kind, file, params.offset, params.length);
@ -990,7 +990,7 @@ class _RefactoringManager {
_checkForReset_afterCreateChange();
result.potentialEdits = nullIfEmpty(refactoring.potentialEditIds);
_sendResultResponse();
}, onError: (exception, stackTrace) {
}, (exception, stackTrace) {
if (exception is _ResetError ||
exception is InconsistentAnalysisException) {
cancel();

View file

@ -128,9 +128,9 @@ class LspByteStreamServerChannel implements LspServerCommunicationChannel {
/// Send [bytes] to [_output].
void _write(List<int> bytes) {
runZoned(
runZonedGuarded(
() => _output.add(bytes),
onError: (e) => close(),
(e, s) => close(),
);
}
}

View file

@ -245,7 +245,7 @@ class LspAnalysisServer extends AbstractAnalysisServer {
/// Handle a [message] that was read from the communication channel.
void handleMessage(Message message) {
performance.logRequestTiming(null);
runZoned(() {
runZonedGuarded(() {
ServerPerformanceStatistics.serverRequests.makeCurrentWhile(() async {
try {
if (message is ResponseMessage) {
@ -284,7 +284,7 @@ class LspAnalysisServer extends AbstractAnalysisServer {
logException(errorMessage, error, stackTrace);
}
});
}, onError: socketError);
}, socketError);
}
/// Logs the error on the client using window/logMessage.

View file

@ -140,10 +140,10 @@ Future listenAsyncStarThrowAsync() async {
Future<void> customErrorZone() async {
final completer = Completer<void>();
runZoned(() async {
runZonedGuarded(() async {
await allYield();
completer.complete(null);
}, onError: (e, s) {
}, (e, s) {
completer.completeError(e, s);
});
return completer.future;
@ -550,7 +550,7 @@ Future<void> doTestsCausal() async {
r'#5 _rootRun ',
r'#6 _CustomZone.run ',
r'#7 _runZoned ',
r'#8 runZoned ',
r'#8 runZonedGuarded ',
r'#9 customErrorZone \(.*/utils.dart:143(:3)?\)$',
];
await doTestAwait(

View file

@ -14,9 +14,9 @@ main(args) async {
{
final caughtErrorCompleter = Completer<String>();
await runZoned(() {
await runZonedGuarded(() {
Isolate.spawn(isolate, x);
}, onError: (e) {
}, (e, s) {
caughtErrorCompleter.complete(e.toString());
});
Expect.equals(

View file

@ -51,27 +51,20 @@ abstract class HttpOverrides {
static R runZoned<R>(R body(),
{HttpClient Function(SecurityContext) createHttpClient,
String Function(Uri uri, Map<String, String> environment)
findProxyFromEnvironment,
ZoneSpecification zoneSpecification,
Function onError}) {
findProxyFromEnvironment}) {
HttpOverrides overrides =
new _HttpOverridesScope(createHttpClient, findProxyFromEnvironment);
return _asyncRunZoned<R>(body,
zoneValues: {_httpOverridesToken: overrides},
zoneSpecification: zoneSpecification,
onError: onError);
zoneValues: {_httpOverridesToken: overrides});
}
/// Runs [body] in a fresh [Zone] using the overrides found in [overrides].
///
/// Note that [overrides] should be an instance of a class that extends
/// [HttpOverrides].
static R runWithHttpOverrides<R>(R body(), HttpOverrides overrides,
{ZoneSpecification zoneSpecification, Function onError}) {
static R runWithHttpOverrides<R>(R body(), HttpOverrides overrides) {
return _asyncRunZoned<R>(body,
zoneValues: {_httpOverridesToken: overrides},
zoneSpecification: zoneSpecification,
onError: onError);
zoneValues: {_httpOverridesToken: overrides});
}
/// Returns a new [HttpClient] using the given [context].

View file

@ -1467,43 +1467,91 @@ const _rootZone = const _RootZone();
* var future2 = future.then((_) { throw "error in first error-zone"; });
* runZoned(() {
* var future3 = future2.catchError((e) { print("Never reached!"); });
* }, onError: (e) { print("unused error handler"); });
* }, onError: (e) { print("catches error of first error-zone."); });
* }, 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: print); // Will print "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.
*/
R runZoned<R>(R body(),
{Map zoneValues, ZoneSpecification zoneSpecification, Function onError}) {
if (onError == null) {
return _runZoned<R>(body, zoneValues, zoneSpecification);
}
void Function(Object) unaryOnError;
void Function(Object, StackTrace) binaryOnError;
if (onError is void Function(Object, StackTrace)) {
binaryOnError = onError;
} else if (onError is void Function(Object)) {
unaryOnError = onError;
} else {
throw new ArgumentError("onError callback must take either an Object "
"(the error), or both an Object (the error) and a StackTrace.");
{Map zoneValues,
ZoneSpecification zoneSpecification,
@Deprecated("Use runZonedGuarded instead") Function onError}) {
ArgumentError.checkNotNull(body, "body");
if (onError != null) {
void Function(Object, StackTrace) typedOnError;
if (onError is void Function(Object, StackTrace)) {
typedOnError = onError;
} else if (onError is void Function(Object)) {
typedOnError = (Object e, StackTrace _) => onError(e);
} else {
throw ArgumentError.value(onError, "onError",
"Should accept one error, or one error and a stack trace");
}
return runZonedGuarded(body, typedOnError,
zoneValues: zoneValues, zoneSpecification: zoneSpecification);
}
return _runZoned<R>(body, zoneValues, 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`.
*
* 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.
*/
@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 {
if (binaryOnError != null) {
self.parent.runBinary(binaryOnError, error, stackTrace);
} else {
assert(unaryOnError != null);
self.parent.runUnary(unaryOnError, error);
}
self.parent.runBinary(onError, error, stackTrace);
} catch (e, s) {
if (identical(e, error)) {
parent.handleUncaughtError(zone, error, stackTrace);
@ -1521,13 +1569,8 @@ R runZoned<R>(R body(),
}
try {
return _runZoned<R>(body, zoneValues, zoneSpecification);
} catch (e, stackTrace) {
if (binaryOnError != null) {
binaryOnError(e, stackTrace);
} else {
assert(unaryOnError != null);
unaryOnError(e);
}
} catch (error, stackTrace) {
onError(error, stackTrace);
}
return null;
}

View file

@ -92,11 +92,7 @@ abstract class IOOverrides {
// ServerSocket
Future<ServerSocket> Function(dynamic, int,
{int backlog, bool v6Only, bool shared})
serverSocketBind,
// Optional Zone parameters
ZoneSpecification zoneSpecification,
Function onError}) {
serverSocketBind}) {
IOOverrides overrides = new _IOOverridesScope(
// Directory
createDirectory,
@ -131,22 +127,15 @@ abstract class IOOverrides {
// ServerSocket
serverSocketBind,
);
return _asyncRunZoned<R>(body,
zoneValues: {_ioOverridesToken: overrides},
zoneSpecification: zoneSpecification,
onError: onError);
return _asyncRunZoned<R>(body, zoneValues: {_ioOverridesToken: overrides});
}
/// Runs [body] in a fresh [Zone] using the overrides found in [overrides].
///
/// Note that [overrides] should be an instance of a class that extends
/// [IOOverrides].
static R runWithIOOverrides<R>(R body(), IOOverrides overrides,
{ZoneSpecification zoneSpecification, Function onError}) {
return _asyncRunZoned<R>(body,
zoneValues: {_ioOverridesToken: overrides},
zoneSpecification: zoneSpecification,
onError: onError);
static R runWithIOOverrides<R>(R body(), IOOverrides overrides) {
return _asyncRunZoned<R>(body, zoneValues: {_ioOverridesToken: overrides});
}
// Directory

View file

@ -49,27 +49,20 @@ abstract class HttpOverrides {
static R runZoned<R>(R body(),
{HttpClient Function(SecurityContext?)? createHttpClient,
String Function(Uri uri, Map<String, String>? environment)?
findProxyFromEnvironment,
ZoneSpecification? zoneSpecification,
Function? onError}) {
findProxyFromEnvironment}) {
HttpOverrides overrides =
new _HttpOverridesScope(createHttpClient, findProxyFromEnvironment);
return _asyncRunZoned<R>(body,
zoneValues: {_httpOverridesToken: overrides},
zoneSpecification: zoneSpecification,
onError: onError);
zoneValues: {_httpOverridesToken: overrides});
}
/// Runs [body] in a fresh [Zone] using the overrides found in [overrides].
///
/// Note that [overrides] should be an instance of a class that extends
/// [HttpOverrides].
static R runWithHttpOverrides<R>(R body(), HttpOverrides overrides,
{ZoneSpecification? zoneSpecification, Function? onError}) {
static R runWithHttpOverrides<R>(R body(), HttpOverrides overrides) {
return _asyncRunZoned<R>(body,
zoneValues: {_httpOverridesToken: overrides},
zoneSpecification: zoneSpecification,
onError: onError);
zoneValues: {_httpOverridesToken: overrides});
}
/// Returns a new [HttpClient] using the given [context].

View file

@ -1465,7 +1465,7 @@ const _Zone _rootZone = const _RootZone();
* If an error occurs synchronously in [body],
* then throwing in the [onError] handler
* makes the call to `runZone` throw that error,
* and otherwise the call to `runZoned` returns `null`.
* and otherwise the call to `runZoned` attempt to return `null`.
*
* If the zone specification has a `handleUncaughtError` value or the [onError]
* parameter is provided, the zone becomes an error-zone.
@ -1474,19 +1474,19 @@ const _Zone _rootZone = const _RootZone();
* Errors that try to cross error-zone boundaries are considered uncaught in
* their originating error zone.
*
* var future = Future.value(499);
* 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) { print("unused error handler"); });
* }, onError: (e) { print("catches error of first error-zone."); });
* }, 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: print); // Will print "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
@ -1495,30 +1495,74 @@ const _Zone _rootZone = const _RootZone();
R runZoned<R>(R body(),
{Map<Object?, Object?>? zoneValues,
ZoneSpecification? zoneSpecification,
Function? onError}) {
if (onError == null) {
return _runZoned<R>(body, zoneValues, zoneSpecification);
}
void Function(Object)? unaryOnError;
void Function(Object, StackTrace)? binaryOnError;
if (onError is void Function(Object, StackTrace)) {
binaryOnError = onError;
} else if (onError is void Function(Object)) {
unaryOnError = onError;
} else {
throw new ArgumentError("onError callback must take either an Object "
"(the error), or both an Object (the error) and a StackTrace.");
@Deprecated("Use runZonedGuarded instead") Function? onError}) {
ArgumentError.checkNotNull(body, "body");
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);
}
/**
* 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.
* ```dart
* 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:
* ```dart
* 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.
*/
@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 {
if (binaryOnError != null) {
parentZone.runBinary(binaryOnError, error, stackTrace);
} else {
assert(unaryOnError != null);
parentZone.runUnary(unaryOnError!, error);
}
parentZone.runBinary(onError, error, stackTrace);
} catch (e, s) {
if (identical(e, error)) {
parent.handleUncaughtError(zone, error, stackTrace);
@ -1536,17 +1580,10 @@ R runZoned<R>(R body(),
}
try {
return _runZoned<R>(body, zoneValues, zoneSpecification);
} catch (e, stackTrace) {
if (binaryOnError != null) {
binaryOnError(e, stackTrace);
} else {
assert(unaryOnError != null);
unaryOnError!(e);
}
} catch (error, stackTrace) {
onError(error, stackTrace);
}
// TODO(lrn): Change behavior to throw the actual resulting error,
// perhaps even synchronously.
return null as R;
return null;
}
/// Runs [body] in a new zone based on [zoneValues] and [specification].

View file

@ -90,11 +90,7 @@ abstract class IOOverrides {
// ServerSocket
Future<ServerSocket> Function(dynamic, int,
{int backlog, bool v6Only, bool shared})?
serverSocketBind,
// Optional Zone parameters
ZoneSpecification? zoneSpecification,
Function? onError}) {
serverSocketBind}) {
IOOverrides overrides = new _IOOverridesScope(
// Directory
createDirectory,
@ -129,22 +125,15 @@ abstract class IOOverrides {
// ServerSocket
serverSocketBind,
);
return _asyncRunZoned<R>(body,
zoneValues: {_ioOverridesToken: overrides},
zoneSpecification: zoneSpecification,
onError: onError);
return _asyncRunZoned<R>(body, zoneValues: {_ioOverridesToken: overrides});
}
/// Runs [body] in a fresh [Zone] using the overrides found in [overrides].
///
/// Note that [overrides] should be an instance of a class that extends
/// [IOOverrides].
static R runWithIOOverrides<R>(R body(), IOOverrides overrides,
{ZoneSpecification? zoneSpecification, Function? onError}) {
return _asyncRunZoned<R>(body,
zoneValues: {_ioOverridesToken: overrides},
zoneSpecification: zoneSpecification,
onError: onError);
static R runWithIOOverrides<R>(R body(), IOOverrides overrides) {
return _asyncRunZoned<R>(body, zoneValues: {_ioOverridesToken: overrides});
}
// Directory

View file

@ -11,7 +11,7 @@ Stream catchErrors(dynamic body()) {
}
void onListen() {
runZoned(body, onError: onError);
runZonedGuarded(body, onError);
}
controller = new StreamController(onListen: onListen);
@ -21,7 +21,7 @@ Stream catchErrors(dynamic body()) {
runZonedScheduleMicrotask(body(),
{void onScheduleMicrotask(void callback()), Function? onError}) {
if (onScheduleMicrotask == null) {
return runZoned(body, onError: onError);
return runZonedGuarded(body, onError);
}
HandleUncaughtErrorHandler errorHandler;
if (onError != null) {

View file

@ -868,7 +868,7 @@ void testWaitCleanUpError() {
asyncStart();
asyncStart();
asyncStart();
runZoned(() {
runZonedGuarded(() {
Future.wait([
new Future.delayed(cms, () => 0),
new Future.delayed(cms * 2, () => throw 1),
@ -882,7 +882,7 @@ void testWaitCleanUpError() {
Expect.equals(e, 1);
asyncEnd();
});
}, onError: (e, s) {
}, (e, s) {
int index = e;
Expect.isTrue(index == 0 || index == 2, "$index");
Expect.isFalse(uncaughts[index]);

View file

@ -10,7 +10,7 @@ main() {
// error handler is defined.
Expect.equals(
499,
runZoned(() => 499, onError: (e) {
runZonedGuarded(() => 499, (e, s) {
throw "Unexpected";
}));
}

View file

@ -9,9 +9,9 @@ import 'dart:async';
main() {
asyncStart();
// Ensure that `runZoned`'s onError handles synchronous errors.
runZoned(() {
runZonedGuarded(() {
throw 0;
}, onError: (e) {
}, (e, s) {
Expect.equals(0, e);
asyncEnd();
});

View file

@ -12,9 +12,9 @@ main() {
// in the error handler at that point (when it is a synchronous error) yields
// a synchronous error.
try {
runZoned(() {
runZonedGuarded(() {
throw 0;
}, onError: (e) {
}, (e, s) {
Expect.equals(0, e);
throw e; //#01 : ok
asyncEnd();

View file

@ -13,7 +13,7 @@ main() {
var events = [];
// Test runZoned with periodic Timers.
runZoned(() {
runZonedGuarded(() {
int counter = 0;
new Timer.periodic(const Duration(milliseconds: 50), (timer) {
if (counter == 1) {
@ -24,7 +24,7 @@ main() {
events.add(counter);
throw counter;
});
}, onError: (e, [s]) {
}, (e, [s]) {
events.add("error: $e");
Expect.isNotNull(s); // Regression test for http://dartbug.com/33589
});

View file

@ -12,15 +12,15 @@ main() {
// to the next runZoned when the handler returns false.
bool sawInnerHandler = false;
try {
runZoned(() {
runZonedGuarded(() {
runZoned(() {
throw 0;
}, onError: (e) {
}, onError: (e, s) {
Expect.equals(0, e);
sawInnerHandler = true;
throw e;
});
}, onError: (e) {
}, (e, s) {
Expect.equals(0, e);
Expect.isTrue(sawInnerHandler);
// If we are waiting for an error, don't asyncEnd, but let it time out.

View file

@ -267,7 +267,7 @@ main() {
bool streamIsDone = false;
int errorCount = 0;
runZoned(() {
runZonedGuarded(() {
controller.stream
.transform(new SinkTransformer((sink) =>
new FutureWaitingTransformerSink(sink, closeCompleter.future)))
@ -280,7 +280,7 @@ main() {
Expect.listEquals([], events);
streamIsDone = true;
});
}, onError: (e) {
}, (e, s) {
Expect.isTrue(e is StateError);
errorCount++;
});

View file

@ -114,7 +114,7 @@ main() {
});
test("subscription.asFuture failure in cancel", () {
runZoned(() {
runZonedGuarded(() {
var completer = new Completer();
var controller =
new StreamController(onCancel: () => completer.future, sync: true);
@ -135,7 +135,7 @@ main() {
Expect.isFalse(catchErrorHasRun);
completer.completeError(499);
}));
}, onError: expectAsync((e) {
}, expectAsync2((e, s) {
Expect.equals(499, e);
}));
});

View file

@ -10,8 +10,8 @@ import 'dart:async';
test1() {
var events = [];
var done = new Completer();
runZoned(() {
runZoned(() {
runZonedGuarded(() {
runZonedGuarded(() {
var c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"),
@ -19,8 +19,8 @@ test1() {
c.add(1);
c.addError(2);
c.close();
}, onError: (x) => events.add("rza: error $x"));
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rza: error $e"));
}, (e, s) => events.add("rzb: error $e"));
return [
done.future,
() {
@ -33,18 +33,18 @@ test1() {
test2() {
var events = [];
var done = new Completer();
runZoned(() {
runZonedGuarded(() {
var c;
runZoned(() {
runZonedGuarded(() {
c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"),
onDone: done.complete);
}, onError: (x) => events.add("rza: error $x"));
}, (e, s) => events.add("rza: error $e"));
c.add(1);
c.addError(2);
c.close();
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rzb: error $e"));
return [
done.future,
() {
@ -57,16 +57,16 @@ test2() {
test3() {
var events = [];
var done = new Completer();
runZoned(() {
runZonedGuarded(() {
var c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"), onDone: done.complete);
runZoned(() {
runZonedGuarded(() {
c.add(1);
c.addError(2);
c.close();
}, onError: (x) => events.add("rza: error $x"));
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rza: error $e"));
}, (e, s) => events.add("rzb: error $e"));
return [
done.future,
() {
@ -79,18 +79,18 @@ test3() {
test4() {
var events = [];
var done = new Completer();
runZoned(() {
runZonedGuarded(() {
var c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"), onDone: done.complete);
runZoned(() {
runZonedGuarded(() {
var c2 = new StreamController();
c.addStream(c2.stream).whenComplete(c.close);
c2.add(1);
c2.addError(2);
c2.close();
}, onError: (x) => events.add("rza: error $x"));
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rza: error $e"));
}, (e, s) => events.add("rzb: error $e"));
return [
done.future,
() {
@ -104,20 +104,20 @@ test4() {
test5() {
var events = [];
var done = new Completer();
runZoned(() {
runZonedGuarded(() {
var c;
runZoned(() {
runZonedGuarded(() {
c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"),
onDone: done.complete);
}, onError: (x) => events.add("rza: error $x"));
}, (e, s) => events.add("rza: error $e"));
var c2 = new StreamController();
c.addStream(c2.stream).whenComplete(c.close);
c2.add(1);
c2.addError(2);
c2.close();
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rzb: error $e"));
return [
done.future,
() {
@ -130,18 +130,18 @@ test6() {
var events = [];
var done = new Completer();
var c;
runZoned(() {
runZonedGuarded(() {
c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"), onDone: done.complete);
}, onError: (x) => events.add("rza: error $x"));
runZoned(() {
}, (e, s) => events.add("rza: error $e"));
runZonedGuarded(() {
var c2 = new StreamController();
c.addStream(c2.stream).whenComplete(c.close);
c2.add(1);
c2.addError(2);
c2.close();
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rzb: error $e, s"));
return [
done.future,
() {
@ -155,16 +155,16 @@ test7() {
var events = [];
var done = new Completer();
var c;
runZoned(() {
runZonedGuarded(() {
c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"), onDone: done.complete);
}, onError: (x) => events.add("rza: error $x"));
runZoned(() {
}, (e, s) => events.add("rza: error $e"));
runZonedGuarded(() {
c.add(1);
c.addError(2);
c.close();
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rzb: error $e"));
return [
done.future,
() {

View file

@ -10,7 +10,7 @@ main() {
// error handler is defined.
Expect.equals(
499,
runZoned(() => 499, onError: (e) {
runZonedGuarded(() => 499, (e, s) {
throw "Unexpected";
}));
}

View file

@ -9,9 +9,9 @@ import 'dart:async';
main() {
asyncStart();
// Ensure that `runZoned`'s onError handles synchronous errors.
runZoned(() {
runZonedGuarded(() {
throw 0;
}, onError: (e) {
}, (e, s) {
Expect.equals(0, e);
asyncEnd();
});

View file

@ -12,9 +12,9 @@ main() {
// in the error handler at that point (when it is a synchronous error) yields
// a synchronous error.
try {
runZoned(() {
runZonedGuarded(() {
throw 0;
}, onError: (e) {
}, (e, s) {
Expect.equals(0, e);
throw e; //#01 : ok
asyncEnd();

View file

@ -12,15 +12,15 @@ main() {
// to the next runZoned when the handler returns false.
bool sawInnerHandler = false;
try {
runZoned(() {
runZoned(() {
runZonedGuarded(() {
runZonedGuarded(() {
throw 0;
}, onError: (e) {
}, (e, s) {
Expect.equals(0, e);
sawInnerHandler = true;
throw e;
});
}, onError: (e) {
}, (e, s) {
Expect.equals(0, e);
Expect.isTrue(sawInnerHandler);
// If we are waiting for an error, don't asyncEnd, but let it time out.

View file

@ -267,7 +267,7 @@ main() {
bool streamIsDone = false;
int errorCount = 0;
runZoned(() {
runZonedGuarded(() {
controller.stream
.transform(new SinkTransformer((sink) =>
new FutureWaitingTransformerSink(sink, closeCompleter.future)))
@ -280,7 +280,7 @@ main() {
Expect.listEquals([], events);
streamIsDone = true;
});
}, onError: (e) {
}, (e, s) {
Expect.isTrue(e is StateError);
errorCount++;
});

View file

@ -114,7 +114,7 @@ main() {
});
test("subscription.asFuture failure in cancel", () {
runZoned(() {
runZonedGuarded(() {
var completer = new Completer();
var controller =
new StreamController(onCancel: () => completer.future, sync: true);
@ -135,7 +135,7 @@ main() {
Expect.isFalse(catchErrorHasRun);
completer.completeError(499);
}));
}, onError: expectAsync((e) {
}, expectAsync2((e, s) {
Expect.equals(499, e);
}));
});

View file

@ -10,8 +10,8 @@ import 'dart:async';
test1() {
var events = [];
var done = new Completer();
runZoned(() {
runZoned(() {
runZonedGuarded(() {
runZonedGuarded(() {
var c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"),
@ -19,8 +19,8 @@ test1() {
c.add(1);
c.addError(2);
c.close();
}, onError: (x) => events.add("rza: error $x"));
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rza: error $e"));
}, (e, s) => events.add("rzb: error $e"));
return [
done.future,
() {
@ -33,18 +33,18 @@ test1() {
test2() {
var events = [];
var done = new Completer();
runZoned(() {
runZonedGuarded(() {
var c;
runZoned(() {
runZonedGuarded(() {
c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"),
onDone: done.complete);
}, onError: (x) => events.add("rza: error $x"));
}, (e, s) => events.add("rza: error $e"));
c.add(1);
c.addError(2);
c.close();
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rzb: error $e"));
return [
done.future,
() {
@ -57,16 +57,16 @@ test2() {
test3() {
var events = [];
var done = new Completer();
runZoned(() {
runZonedGuarded(() {
var c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"), onDone: done.complete);
runZoned(() {
runZonedGuarded(() {
c.add(1);
c.addError(2);
c.close();
}, onError: (x) => events.add("rza: error $x"));
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rza: error $e"));
}, (e, s) => events.add("rzb: error $e"));
return [
done.future,
() {
@ -79,18 +79,18 @@ test3() {
test4() {
var events = [];
var done = new Completer();
runZoned(() {
runZonedGuarded(() {
var c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"), onDone: done.complete);
runZoned(() {
runZonedGuarded(() {
var c2 = new StreamController();
c.addStream(c2.stream).whenComplete(c.close);
c2.add(1);
c2.addError(2);
c2.close();
}, onError: (x) => events.add("rza: error $x"));
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rza: error $e"));
}, (e, s) => events.add("rzb: error $e"));
return [
done.future,
() {
@ -104,20 +104,20 @@ test4() {
test5() {
var events = [];
var done = new Completer();
runZoned(() {
runZonedGuarded(() {
var c;
runZoned(() {
runZonedGuarded(() {
c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"),
onDone: done.complete);
}, onError: (x) => events.add("rza: error $x"));
}, (e, s) => events.add("rza: error $e"));
var c2 = new StreamController();
c.addStream(c2.stream).whenComplete(c.close);
c2.add(1);
c2.addError(2);
c2.close();
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rzb: error $e"));
return [
done.future,
() {
@ -130,18 +130,18 @@ test6() {
var events = [];
var done = new Completer();
var c;
runZoned(() {
runZonedGuarded(() {
c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"), onDone: done.complete);
}, onError: (x) => events.add("rza: error $x"));
runZoned(() {
}, (e, s) => events.add("rza: error $e"));
runZonedGuarded(() {
var c2 = new StreamController();
c.addStream(c2.stream).whenComplete(c.close);
c2.add(1);
c2.addError(2);
c2.close();
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rzb: error $e"));
return [
done.future,
() {
@ -155,16 +155,16 @@ test7() {
var events = [];
var done = new Completer();
var c;
runZoned(() {
runZonedGuarded(() {
c = new StreamController();
c.stream.listen((x) => events.add("stream: $x"),
onError: (x) => events.add("stream: error $x"), onDone: done.complete);
}, onError: (x) => events.add("rza: error $x"));
runZoned(() {
}, (e, s) => events.add("rza: error $e"));
runZonedGuarded(() {
c.add(1);
c.addError(2);
c.close();
}, onError: (x) => events.add("rzb: error $x"));
}, (e, s) => events.add("rzb: error $e"));
return [
done.future,
() {

View file

@ -12,11 +12,11 @@ var events = [];
Future testSocketException() {
var completer = new Completer();
runZoned(() {
runZonedGuarded(() {
Socket.connect("4", 1).then((Socket s) {
Expect.fail("Socket should not be able to connect");
});
}, onError: (err) {
}, (err, s) {
if (err is! SocketException) Expect.fail("Not expected error: $err");
completer.complete("socket test, ok.");
events.add("SocketException");
@ -26,9 +26,9 @@ Future testSocketException() {
Future testFileSystemException() {
var completer = new Completer();
runZoned(() {
runZonedGuarded(() {
new File("lol it's not a file\n").openRead().listen(null);
}, onError: (err) {
}, (err, s) {
if (err is! FileSystemException) Expect.fail("Not expected error: $err");
completer.complete("file test, ok.");
events.add("FileSystemException");

View file

@ -452,11 +452,11 @@ testWatchOverflow() async {
}
void watcher(SendPort sendPort) async {
runZoned(() {
runZonedGuarded(() {
var watcher = Directory.systemTemp.watch(recursive: true);
watcher.listen((data) async {});
sendPort.send('start');
}, onError: (error) {
}, (error, stack) {
print(error);
sendPort.send('end');
});

View file

@ -159,7 +159,7 @@ void testHttpServerZone() {
void testHttpServerZoneError() {
asyncStart();
Expect.equals(Zone.root, Zone.current);
runZoned(() {
runZonedGuarded(() {
Expect.notEquals(Zone.root, Zone.current);
HttpServer.bind("127.0.0.1", 0).then((server) {
Expect.notEquals(Zone.root, Zone.current);
@ -178,14 +178,14 @@ void testHttpServerZoneError() {
socket.listen(null);
});
});
}, onError: (e) {
}, (e, s) {
asyncEnd();
});
}
void testHttpServerClientClose() {
HttpServer.bind("127.0.0.1", 0).then((server) {
runZoned(() {
runZonedGuarded(() {
server.listen((request) {
request.response.bufferOutput = false;
request.response.add(new Uint8List(64 * 1024));
@ -195,7 +195,7 @@ void testHttpServerClientClose() {
});
});
});
}, onError: (e, s) {
}, (e, s) {
Expect.fail("Unexpected error: $e(${e.hashCode})\n$s");
});
var client = new HttpClient();

View file

@ -426,7 +426,7 @@ void testSocketZone() {
void testSocketZoneError() {
asyncStart();
Expect.equals(Zone.root, Zone.current);
runZoned(() {
runZonedGuarded(() {
Expect.notEquals(Zone.root, Zone.current);
RawServerSocket.bind(InternetAddress.loopbackIPv4, 0).then((server) {
Expect.notEquals(Zone.root, Zone.current);
@ -451,7 +451,7 @@ void testSocketZoneError() {
socket.close();
});
});
}, onError: (e) {
}, (e, s) {
asyncEnd();
});
}

View file

@ -17,12 +17,12 @@ main() {
initWaitForEvent();
asyncStart();
bool flag = false;
runZoned(() {
runZonedGuarded(() {
Timer.run(() {
asyncEnd();
throw "Exception";
});
}, onError: (e) {
}, (e, s) {
flag = true;
});
Expect.isFalse(flag);

View file

@ -11,12 +11,12 @@ import 'package:expect/expect.dart';
main() {
asyncStart();
Completer<bool> c = new Completer<bool>();
runZoned(() {
runZonedGuarded(() {
Timer.run(() {
asyncEnd();
throw "Error";
});
}, onError: (e) {
}, (e, s) {
Expect.isTrue(e is String);
c.complete(true);
});

View file

@ -12,11 +12,11 @@ var events = [];
Future testSocketException() {
var completer = new Completer();
runZoned(() {
runZonedGuarded(() {
Socket.connect("4", 1).then((Socket s) {
Expect.fail("Socket should not be able to connect");
});
}, onError: (err) {
}, (err, s) {
if (err is! SocketException) Expect.fail("Not expected error: $err");
completer.complete("socket test, ok.");
events.add("SocketException");
@ -26,9 +26,9 @@ Future testSocketException() {
Future testFileSystemException() {
var completer = new Completer();
runZoned(() {
runZonedGuarded(() {
new File("lol it's not a file\n").openRead().listen(null);
}, onError: (err) {
}, (err, s) {
if (err is! FileSystemException) Expect.fail("Not expected error: $err");
completer.complete("file test, ok.");
events.add("FileSystemException");

View file

@ -451,11 +451,11 @@ testWatchOverflow() async {
}
void watcher(SendPort sendPort) async {
runZoned(() {
runZonedGuarded(() {
var watcher = Directory.systemTemp.watch(recursive: true);
watcher.listen((data) async {});
sendPort.send('start');
}, onError: (error) {
}, (error, stack) {
print(error);
sendPort.send('end');
});

View file

@ -159,7 +159,7 @@ void testHttpServerZone() {
void testHttpServerZoneError() {
asyncStart();
Expect.equals(Zone.root, Zone.current);
runZoned(() {
runZonedGuarded(() {
Expect.notEquals(Zone.root, Zone.current);
HttpServer.bind("127.0.0.1", 0).then((server) {
Expect.notEquals(Zone.root, Zone.current);
@ -178,14 +178,14 @@ void testHttpServerZoneError() {
socket.listen(null);
});
});
}, onError: (e) {
}, (e, s) {
asyncEnd();
});
}
void testHttpServerClientClose() {
HttpServer.bind("127.0.0.1", 0).then((server) {
runZoned(() {
runZonedGuarded(() {
server.listen((request) {
request.response.bufferOutput = false;
request.response.add(new Uint8List(64 * 1024));
@ -195,7 +195,7 @@ void testHttpServerClientClose() {
});
});
});
}, onError: (e, s) {
}, (e, s) {
Expect.fail("Unexpected error: $e(${e.hashCode})\n$s");
});
var client = new HttpClient();

View file

@ -429,7 +429,7 @@ void testSocketZone() {
void testSocketZoneError() {
asyncStart();
Expect.equals(Zone.root, Zone.current);
runZoned(() {
runZonedGuarded(() {
Expect.notEquals(Zone.root, Zone.current);
RawServerSocket.bind(InternetAddress.loopbackIPv4, 0).then((server) {
Expect.notEquals(Zone.root, Zone.current);
@ -454,7 +454,7 @@ void testSocketZoneError() {
socket.close();
});
});
}, onError: (e) {
}, (e, s) {
asyncEnd();
});
}

View file

@ -17,12 +17,12 @@ main() {
initWaitForEvent();
asyncStart();
bool flag = false;
runZoned(() {
runZonedGuarded(() {
Timer.run(() {
asyncEnd();
throw "Exception";
});
}, onError: (e) {
}, (e, s) {
flag = true;
});
Expect.isFalse(flag);

View file

@ -11,12 +11,12 @@ import 'package:expect/expect.dart';
main() {
asyncStart();
Completer<bool> c = new Completer<bool>();
runZoned(() {
runZonedGuarded(() {
Timer.run(() {
asyncEnd();
throw "Error";
});
}, onError: (e) {
}, (e, s) {
Expect.isTrue(e is String);
c.complete(true);
});