I am not sure if this type of error handling and abstraction is done in a wrong way.
Future<void> _refresh() {
return Future(() => throw someError)
.catchError((error) {
// maybe do something here
throw abstractedError; //or even the same error
});
Being able in another place to use it accordingly:
// in a widget/another place
void doSomething() {
_refresh()
.then((_) => bla())
.catchError((error) {
//showSomeAlert() or handleSomething()
});
}
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 ... )
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