Поймать ошибку с помощью catchError в будущем и выдать другой тип

Я не уверен, что этот тип обработки ошибок и абстракции выполняется неправильно.

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()
  });
}

Вы должны обернуть это в блок try catch.

CopsOnRoad 09.04.2019 17:25

Моя проблема возникает при использовании мокито вместе с этим шаблоном, и это заставляет меня подозревать, что у меня неправильное понимание этого.

Durdu 09.04.2019 17:25

@CopsOnRoad, пожалуйста, перепроверьте после моего обновления

Durdu 09.04.2019 17:30

@CopsOnRoad Я знаю, что могу обернуть это в trycatch, но мне было интересно использовать фьючерсы для цепочки вещей.

Durdu 09.04.2019 17:31
14
4
27 358
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ваше решение должно работать (просто 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 возвращает будущее, и, похоже, нет никаких проблем, чтобы выдать ошибку из любого будущего.

Durdu 10.04.2019 08:11
Ответ принят как подходящий

У нас есть во флаттер-фреймворке описание функции 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');
  }

Другие вопросы по теме