Future catchError function doesn't catch error when its not chained immediately
Solution 1:
The error is leaked because you are awaiting the result on a Future
which ends up being completed with an error in:
await fetch();
It is important to understand that a Future
object is just a value which gets a value sometimes in the future and this value can either be a value or an error.
The catchError()
is a way to subscribe some code to be executed if the Future
gets completed as an error. The method returns a new future with the logic that it gets the origin value in case of the origin future gets completed without any error. But if the origin gets completed with an error, the catchError()
runs a specified method and returns the value after this execution.
The catchError()
does not change anything about the origin Future
and you can therefore call catchError()
as many times you want.
I should add that I think it is better to use a traditional try...catch (combined with await
) inside async-marked functions instead of playing with catchError()
since it makes the code more readable and less confusing:
Future<void> fetch() async {
try {
await fakeCall();
} catch (e) {
print('on error');
} finally {
print('when completed');
}
}
void main() async {
await fetch();
}
Outputs:
on error
when completed
Update after question was changed
The problem with "Example B" is that you assume that whenComplete()
does handle any errors. But if you read the the documentation:
The future returned by this call,
f
, will complete the same way as this future unless an error occurs in theaction
call, or in a Future returned by theaction
call. If the call toaction
does not return a future, its return value is ignored.
https://api.dart.dev/stable/2.15.1/dart-async/Future/whenComplete.html
So the returned Future
have not changed its behavior so if the origin Future
completes with an error, the same is happening with the Future
created from whenComplete()
. And since you are not attaching any error handling on this Future
, your program fails.