Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(950)

Unified Diff: sdk/lib/async/future.dart

Issue 2252823004: Deal with synchronous errors in Future.wait. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « CHANGELOG.md ('k') | tests/lib/async/future_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/async/future.dart
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index b4d9c243393cb33fd47e1be15d4f25e71c8961fe..c64e1c5e0316ca6baa5997c9eb131f6b768bb9bd 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -287,32 +287,51 @@ abstract class Future<T> {
}
}
- // As each future completes, put its value into the corresponding
- // position in the list of values.
- for (Future future in futures) {
- int pos = remaining++;
- future.then((Object/*=T*/ value) {
- remaining--;
- if (values != null) {
- values[pos] = value;
- if (remaining == 0) {
- result._completeWithValue(values);
- }
- } else {
- if (cleanUp != null && value != null) {
- // Ensure errors from cleanUp are uncaught.
- new Future.sync(() { cleanUp(value); });
- }
- if (remaining == 0 && !eagerError) {
- result._completeError(error, stackTrace);
+ try {
+ // As each future completes, put its value into the corresponding
+ // position in the list of values.
+ for (Future future in futures) {
+ int pos = remaining;
+ future.then((Object/*=T*/ value) {
+ remaining--;
+ if (values != null) {
+ values[pos] = value;
+ if (remaining == 0) {
+ result._completeWithValue(values);
+ }
+ } else {
+ if (cleanUp != null && value != null) {
+ // Ensure errors from cleanUp are uncaught.
+ new Future.sync(() { cleanUp(value); });
+ }
+ if (remaining == 0 && !eagerError) {
+ result._completeError(error, stackTrace);
+ }
}
- }
- }, onError: handleError);
- }
- if (remaining == 0) {
- return new Future.value(const []);
+ }, onError: handleError);
+ // Increment the 'remaining' after the call to 'then'.
+ // If that call throws, we don't expect any future callback from
+ // the future, and we also don't increment remaining.
+ remaining++;
+ }
+ if (remaining == 0) {
+ return new Future.value(const []);
+ }
+ values = new List/*<T>*/(remaining);
+ } catch (e, st) {
+ // The error must have been thrown while iterating over the futures
+ // list, or while installing a callback handler on the future.
+ if (remaining == 0 || eagerError) {
+ // Just complete the error immediately.
+ result._completeError(e, st);
+ } else {
+ // Don't allocate a list for values, thus indicating that there was an
+ // error.
+ // Set error to the caught exception.
+ error = e;
+ stackTrace = st;
+ }
}
- values = new List/*<T>*/(remaining);
return result;
}
« no previous file with comments | « CHANGELOG.md ('k') | tests/lib/async/future_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698