Я не уверен, что этот тип обработки ошибок и абстракции выполняется неправильно.
Future<void> _refresh() {
return Future(() => throw someError)
.catchError((error) {
// maybe do something here
throw abstractedError; //or even the same error
});
Возможность в другом месте использовать его соответственно:
// in a widget/another place
void doSomething() {
_refresh()
.then((_) => bla())
.catchError((error) {
//showSomeAlert() or handleSomething()
});
}
Моя проблема возникает при использовании мокито вместе с этим шаблоном, и это заставляет меня подозревать, что у меня неправильное понимание этого.
@CopsOnRoad, пожалуйста, перепроверьте после моего обновления
@CopsOnRoad Я знаю, что могу обернуть это в trycatch, но мне было интересно использовать фьючерсы для цепочки вещей.
Ваше решение должно работать (просто throw
еще одно исключение), но, вероятно, более выразительным способом является использование 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());
});
}
а затем использовать
someApi()
.then((val) { print("success"); })
.catchError((error, stackTrace) {
// error is SecondError
print("outer: $error");
});
Вы можете поиграть с ним по адресу: https://dartpad.dartlang.org/8fef76c5ba1c76a23042025097ed3e0a
Спасибо! Я также заметил, что catchError возвращает будущее, и, похоже, нет никаких проблем, чтобы выдать ошибку из любого будущего.
У нас есть во флаттер-фреймворке описание функции catch:
- Handles errors emitted by this [Future].
- This is the asynchronous equivalent of a "catch" block. ... Future catchError(Function onError, {bool test(Object error)});
При цепочке фьючерсов я бы не советовал использовать:
throw error;
и вместо этого используйте:
return Future.error(SecondError());
Это потому, что если вы свяжете будущее и ожидаете поймать ошибку, используя будущее catchError, у вас возникнет следующая проблема.
Future<void> _refresh() {
return throw Exception("Exception");
}
void main() {
_refresh() // .then((_) => print("bla"))
.catchError(() => print("not able to be reached"));
}
И вы получите ошибку Неперехваченное исключение: Исключение: Исключение.
Это похоже на использование RX (в целом), и вместо броска вы отправляете по цепочке Sigle.error (или любой другой наблюдаемый с ошибкой).
TLDR:
При работе с Фьючерсы и их цепочке (включая catchError) используйте Будущее.ошибка(Исключение("Исключение")) для обработки ошибок.
Если вы используете бросать, убедитесь, что вы окружили его Попробуйте поймать или Будущее (() -> бросить ...).
Чтобы иметь возможность ловить Error
, нужно добавить импорт dart:async
; сначала, затем используйте блок try
..catch
для переноса кода.
try {
Http.Response response = await Http.get(
url,
headers: headers,
)
.timeout(const Duration(seconds: 1));
} on TimeoutException catch (e) {
print('Timeout');
} on Error catch (e) {
print('Error: $e');
}
Вы должны обернуть это в блок
try catch
.