Properly handle synchronous errors in Chain.capture.
R=rnystrom@google.com
BUG=19542
Review URL: https://codereview.chromium.org//344953002
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/stack_trace@37520 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkgs/stack_trace/CHANGELOG.md b/pkgs/stack_trace/CHANGELOG.md
index 0b3553f..a58190f 100644
--- a/pkgs/stack_trace/CHANGELOG.md
+++ b/pkgs/stack_trace/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.1
+
+* Synchronous errors in the [Chain.capture] callback are now handled correctly.
+
## 1.0.0
* No API changes, just declared stable.
diff --git a/pkgs/stack_trace/lib/src/chain.dart b/pkgs/stack_trace/lib/src/chain.dart
index a097bba..78c6ae4 100644
--- a/pkgs/stack_trace/lib/src/chain.dart
+++ b/pkgs/stack_trace/lib/src/chain.dart
@@ -90,7 +90,14 @@
/// [15105]: https://code.google.com/p/dart/issues/detail?id=15105
static capture(callback(), {ChainHandler onError}) {
var spec = new StackZoneSpecification(onError);
- return runZoned(callback, zoneSpecification: spec.toSpec(), zoneValues: {
+ return runZoned(() {
+ try {
+ return callback();
+ } catch (error, stackTrace) {
+ // TODO(nweiz): Don't special-case this when issue 19566 is fixed.
+ return Zone.current.handleUncaughtError(error, stackTrace);
+ }
+ }, zoneSpecification: spec.toSpec(), zoneValues: {
#stack_trace.stack_zone.spec: spec
});
}
diff --git a/pkgs/stack_trace/pubspec.yaml b/pkgs/stack_trace/pubspec.yaml
index ddad7f9..1c43efd 100644
--- a/pkgs/stack_trace/pubspec.yaml
+++ b/pkgs/stack_trace/pubspec.yaml
@@ -1,5 +1,5 @@
name: stack_trace
-version: 1.0.0
+version: 1.0.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 3347deb..beb4721 100644
--- a/pkgs/stack_trace/test/chain_test.dart
+++ b/pkgs/stack_trace/test/chain_test.dart
@@ -14,6 +14,15 @@
void main() {
group('capture() with onError catches exceptions', () {
+ test('thrown synchronously', () {
+ return captureFuture(() => throw 'error')
+ .then((chain) {
+ expect(chain.traces, hasLength(1));
+ expect(chain.traces.single.frames.first,
+ frameMember(startsWith('main')));
+ });
+ });
+
test('thrown in a microtask', () {
return captureFuture(() => inMicrotask(() => throw 'error'))
.then((chain) {