Properly handle errors thrown in [Chain.capture]'s [onError] handler. The Zone infrastructure apparently doesn't automatically pipe errors to the parent Zone (issue 18134). R=rnystrom@google.com BUG= Review URL: https://codereview.chromium.org//232123003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/stack_trace@34904 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkgs/stack_trace/CHANGELOG.md b/pkgs/stack_trace/CHANGELOG.md index 5e2f2c7..0b45208 100644 --- a/pkgs/stack_trace/CHANGELOG.md +++ b/pkgs/stack_trace/CHANGELOG.md
@@ -1,3 +1,9 @@ +## 0.9.3+1 + +* If an error is thrown in `Chain.capture`'s `onError` handler, that error is + handled by the parent zone. This matches the behavior of `runZoned` in + `dart:async`. + ## 0.9.3 * Add a `Chain.foldFrames` method that parallels `Trace.foldFrames`.
diff --git a/pkgs/stack_trace/lib/src/stack_zone_specification.dart b/pkgs/stack_trace/lib/src/stack_zone_specification.dart index 36e0717..9a4f7c0 100644 --- a/pkgs/stack_trace/lib/src/stack_zone_specification.dart +++ b/pkgs/stack_trace/lib/src/stack_zone_specification.dart
@@ -145,10 +145,21 @@ /// [_onError] or [parent]'s error handler. handleUncaughtError(Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace) { + var stackChain = chainFor(stackTrace); if (_onError == null) { - return parent.handleUncaughtError(zone, error, chainFor(stackTrace)); - } else { - _onError(error, chainFor(stackTrace)); + return parent.handleUncaughtError(zone, error, stackChain); + } + + // TODO(nweiz): Currently this copies a lot of logic from [runZoned]. Just + // allow [runBinary] to throw instead once issue 18134 is fixed. + try { + return parent.runBinary(zone, _onError, error, stackChain); + } catch (newError, newStackTrace) { + if (identical(newError, error)) { + return parent.handleUncaughtError(zone, error, stackChain); + } else { + return parent.handleUncaughtError(zone, newError, newStackTrace); + } } }
diff --git a/pkgs/stack_trace/pubspec.yaml b/pkgs/stack_trace/pubspec.yaml index 99abed7..d0cc30f 100644 --- a/pkgs/stack_trace/pubspec.yaml +++ b/pkgs/stack_trace/pubspec.yaml
@@ -1,5 +1,5 @@ name: stack_trace -version: 0.9.3 +version: 0.9.3+1 author: "Dart Team <misc@dartlang.org>" homepage: http://www.dartlang.org description: >
diff --git a/pkgs/stack_trace/test/chain_test.dart b/pkgs/stack_trace/test/chain_test.dart index d9915eb..683544f 100644 --- a/pkgs/stack_trace/test/chain_test.dart +++ b/pkgs/stack_trace/test/chain_test.dart
@@ -107,6 +107,29 @@ return completer.future; }); + + test('and relays them to the parent zone', () { + var completer = new Completer(); + + runZoned(() { + Chain.capture(() { + inMicrotask(() => throw 'error'); + }, onError: (error, chain) { + expect(error, equals('error')); + expect(chain.traces[1].frames, + contains(frameMember(startsWith('inMicrotask')))); + throw error; + }); + }, onError: (error, chain) { + expect(error, equals('error')); + expect(chain, new isInstanceOf<Chain>()); + expect(chain.traces[1].frames, + contains(frameMember(startsWith('inMicrotask')))); + completer.complete(); + }); + + return completer.future; + }); }); test('capture() without onError passes exceptions to parent zone', () {