| 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;
|
| }
|
|
|
|
|