Catch error using catchError in a future and throw another type
Your solution should work (simply throw
another exception), but a more expressive way is probably to use Future.error
:
Future<void> someApi() {
return Future(() {
throw FirstError();
}).catchError((error, stackTrace) {
print("inner: $error");
// although `throw SecondError()` has the same effect.
return Future.error(SecondError());
});
}
and then use
someApi()
.then((val) { print("success"); })
.catchError((error, stackTrace) {
// error is SecondError
print("outer: $error");
});
You can play around with it at: https://dartpad.dartlang.org/8fef76c5ba1c76a23042025097ed3e0a
We have in the flutter framework the description for the catch function:
- Handles errors emitted by this [Future].
- This is the asynchronous equivalent of a "catch" block. ... Future catchError(Function onError, {bool test(Object error)});
When chaining futures I would advise against of using:
throw error;
and instead use:
return Future.error(SecondError());
This is because if you chain a future and expect to catch the error using the catchError future you will have the following problem.
Future<void> _refresh() {
return throw Exception("Exception");
}
void main() {
_refresh() // .then((_) => print("bla"))
.catchError(() => print("not able to be reached"));
}
And you will get an error Uncaught exception: Exception: Exception.
This is similar when using RX (in general) and instead of throwing you send down the chain a Sigle.error (or any other observable with error).
TLDR:
When working with Futures and chaining them (including catchError) use Future.error(Exception("Exception")) to handle errors.
If you are using throw make sure or surround with try catch or Future(() -> throw ... )