If I have the following code:
Future<int> a = new Future(() { print('a'); return 1; });
Future<int> b = new Future.error('Error!');
Future<int> c = new Future(() { print('c'); return 3; });
Future.wait([a, b, c])
.then((List<int> values) => print(values))
.catchError((e) => print(e));
What is printed?
Does the error caught by catchError
have any idea of what Future died? Or which Futures remain?
Sometimes you need to have results of multiple async functions before starting to work on something else. To prevent multiple awaits, chaining futures in . then(), you can simply use Future. wait([]) that returns an array of results you were waiting for.
Error handling within then() For more granular error handling, you can register a second ( onError ) callback within then() to handle Futures completed with errors. Here is then() 's signature: Future<R> then<R>(FutureOr<R> Function(T value) onValue, {Function? onError});
Determining what is printed is pretty easy by running it (do you not have a Dart VM handy?):
a c AsyncError: 'Error!'
The documentation for Future.wait() says:
Wait for all the given futures to complete and collect their values.
Returns a future which will complete once all the futures in a list are complete. If any of the futures in the list completes with an error, the resulting future also completes with an error. Otherwise the value of the returned future will be a list of all the values that were produced.
e.error
is the value that was created with ('Error!'
, in this case), so by setting that to something indicating which Future has the error, you can see which Future "died". Of course, if you're not the one creating the error, that doesn't help.
In general, I think you use Future.wait()
on a List like this when an error in any of them would be handled similarly. Needing to know which one failed might be a sign that you don't want to wait()
on all of them together.
Update: I just realized the question title asks a question not asked in the question body: What happens to the other Futures?
The other Futures keep running. The Future returned by wait()
throws whichever error it receives as soon as it receives it, so all return values are lost, and if any of the other Futures throws an error, it isn't caught, but each Future still runs until returning or throwing an error.
AFAIK, you won't know precisely which Future generated the error. But, you can query the error object and get some useful information:
Future.wait([a, b, c])
.then((List<int> values) => print(values))
.catchError((e) {
print(e.error);
print(e.stackTrace);
print(e.runtimeType);
print(e.error.runtimeType);
});
Running this prints:
a
c
Error!
null
AsyncError
String
This tells us that the original error was a String. I don't know how useful that is to you, but its something.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With