Index: sdk/lib/_internal/pub/lib/src/utils.dart |
diff --git a/sdk/lib/_internal/pub/lib/src/utils.dart b/sdk/lib/_internal/pub/lib/src/utils.dart |
index 222941ad9f2d012f285f614f0ab82004d85a3d6a..ec84b83333fa8ce35c7362a785f56947bfab8f2a 100644 |
--- a/sdk/lib/_internal/pub/lib/src/utils.dart |
+++ b/sdk/lib/_internal/pub/lib/src/utils.dart |
@@ -77,9 +77,6 @@ class FutureGroup<T> { |
Future<List> get future => _completer.future; |
} |
-/// Like [Future.sync], but wraps the Future in [Chain.track] as well. |
-Future syncFuture(callback()) => Chain.track(new Future.sync(callback)); |
- |
/// Returns a buffered stream that will emit the same values as the stream |
/// returned by [future] once [future] completes. |
/// |
@@ -131,6 +128,37 @@ Stream futureStream(Future<Stream> future, {bool broadcast: false}) { |
/// under the covers. |
Future newFuture(callback()) => new Future.value().then((_) => callback()); |
+/// Like [new Future.sync], but automatically wraps the future in a |
+/// [Chain.track] call. |
+Future syncFuture(callback()) => Chain.track(new Future.sync(callback)); |
+ |
+/// Runs [callback] in an error zone and pipes any unhandled error to the |
+/// returned [Future]. |
+/// |
+/// If the returned [Future] produces an error, its stack trace will always be a |
+/// [Chain]. By default, this chain will contain only the local stack trace, but |
+/// if [captureStackChains] is passed, it will contain the full stack chain for |
+/// the error. |
+Future captureErrors(Future callback(), {bool captureStackChains: false}) { |
Bob Nystrom
2013/12/17 00:18:03
How about "captureErrorsIn"?
nweiz
2013/12/17 00:23:05
I think it's clear when reading the code that you'
|
+ var completer = new Completer(); |
+ var wrappedCallback = () { |
+ new Future.sync(callback).then(completer.complete) |
+ .catchError((e, stackTrace) { |
+ completer.completeError(e, new Chain.forTrace(stackTrace)); |
+ }); |
+ }; |
+ |
+ if (captureStackChains) { |
+ Chain.capture(wrappedCallback, onError: completer.completeError); |
+ } else { |
+ runZoned(wrappedCallback, onError: (e, stackTrace) { |
+ completer.completeError(e, new Chain([new Trace.from(stackTrace)])); |
+ }); |
+ } |
+ |
+ return completer.future; |
+} |
+ |
/// Returns a [StreamTransformer] that will call [onDone] when the stream |
/// completes. |
/// |
@@ -411,7 +439,7 @@ Future streamFirst(Stream stream) { |
}, onError: (e, [stackTrace]) { |
completer.completeError(e, stackTrace); |
}, onDone: () { |
- completer.completeError(new StateError("No elements")); |
+ completer.completeError(new StateError("No elements"), new Chain.current()); |
}, cancelOnError: true); |
return completer.future; |
} |