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) {