Пользовательское исключение Flutter не выбрасывает

#flutter #dart #future

Вопрос:

Я обновил Flutter с версии 2.0.2 до версии 2.2.2, и теперь пользовательские исключения, создаваемые будущей функцией, не улавливаются.

Например, у меня есть функция Future, в которой я вызываю другое будущее, которое выполняет запрос сервера и возвращает ответ или создает пользовательское исключение (исключение ApiException) в случае ошибки:

 static Future<bool> signUpCustomerRequest(Map<String, dynamic> params) async {
    try {
      // Here we call this Future function that will do a request to server API.
      dynamic _response = await _provider.signUpCustomer(params);

      if (_response != null) {
        updateUserData(_response);

        return true;
      }

      return false;
    } on ApiException catch(ae) {
      // This custom exception is not being catch
      ae.printDetails();

      rethrow;
    } catch(e) {
      // This catch is working and the print below shows that e is Instance of 'ApiException'
      print("ERROR signUpCustomerRequest: $e");
      rethrow;
    } finally {

    }
  }
 

И это будущая функция, которая выполняет запрос к серверу и выдает исключение ApiException:

 Future<User?> signUpCustomer(Map<String, dynamic> params) async {
    // POST request to server
    var _response = await _requestPOST(
      needsAuth: false,
      path: routes["signup_client"],
      formData: params,
    );

    // Here we check the response...
    var _rc = _response["rc"];

    switch(_rc) {
      case 0:
        if (_response["data"] != null) {
          User user = User.fromJson(_response["data"]["user"]);

          return user;
        }

        return null;
      default:
        print("here default: $_rc");

        // And here we have the throw of the custom exception (ApiException)
        throw ApiException(getRCMessage(_rc), _rc);
    }
  }
 

До обновления до Flutter 2.2.2 улов пользовательских исключений работал отлично. Что — то изменилось в этой версии Flutter? Я делаю что-то не так?

Спасибо!

Ответ №1:

Я смог воспроизвести вашу ошибку со следующим кодом:

 class ApiException implements Exception {
  void printDetails() {
    print("ApiException was caught");
  }
}

Future<void> doSomething() async {
  await Future.delayed(Duration(seconds: 1));
  
  throw ApiException();
}

void main() async {
  try {
    await doSomething();
  } on ApiException catch (ae) {
    ae.printDetails();
  } catch (e) {
    print("Uncaught error: $e"); // This line is printed
  }
}
 

В sdk dart есть открытая проблема, которая, я думаю, может быть связана, хотя я не уверен: https://github.com/dart-lang/sdk/issues/45952.

В любом случае, я смог исправить ошибку , вернув a Future.error , вместо того, чтобы выбрасывать ошибку напрямую:

 class ApiException implements Exception {
  void printDetails() {
    print("ApiException was caught"); // This line is printed
  }
}

Future<void> doSomething() async {
  await Future.delayed(Duration(seconds: 1));
  
  return Future.error(ApiException());
}

void main() async {
  try {
    await doSomething();
  } on ApiException catch (ae) {
    ae.printDetails();
  } catch (e) {
    print("Uncaught error: $e");
  }
}
 

Комментарии:

1. Спасибо, что проверили это! Я пробовал с Future.error, но у меня это не работает.

2. Ах, жаль это слышать — Это было даже с возвращением будущего.ошибка, а не выбрасывание ее?

3. Да, не получилось вернуть или выбросить его.