如何在Flutter中捕获异常?

49

这是我的异常类。Flutter的抽象异常类已经实现了异常类。我是否遗漏了什么?

class FetchDataException implements Exception {
 final _message;
 FetchDataException([this._message]);

String toString() {
if (_message == null) return "Exception";
  return "Exception: $_message";
 }
}


void loginUser(String email, String password) {
  _data
    .userLogin(email, password)
    .then((user) => _view.onLoginComplete(user))
    .catchError((onError) => {
       print('error caught');
       _view.onLoginError();
    });
}

Future < User > userLogin(email, password) async {
  Map body = {
    'username': email,
    'password': password
  };
  http.Response response = await http.post(apiUrl, body: body);
  final responseBody = json.decode(response.body);
  final statusCode = response.statusCode;
  if (statusCode != HTTP_200_OK || responseBody == null) {
    throw new FetchDataException(
      "An error occured : [Status Code : $statusCode]");
   }
  return new User.fromMap(responseBody);
}

CatchError在状态码不为200时无法捕获错误。简而言之,未打印出捕获到的错误。


你的问题“如何在Flutter中捕获异常?”是一般性的,但你的代码是个人的。有人能解释一下如何在Flutter中捕获和打印错误吗? - user14023416
5个回答

75

尝试

void loginUser(String email, String password) async {
  try {
    var user = await _data
      .userLogin(email, password);
    _view.onLoginComplete(user);
      });
  } on FetchDataException catch(e) {
    print('error caught: $e');
    _view.onLoginError();
  }
}

catchError有时不太容易正确处理。 使用async/await,您可以像同步代码一样使用try/catch,通常更容易正确处理。


1
Günter,我认为我们不能在方法参数结束后使用await。你应该在那里使用async。我现在没有IDE,所以无法检查await是否有效。 - CopsOnRoad
1
谢谢,应该是“async”。 - Günter Zöchbauer

21

假设这是你的函数,抛出一个异常:

Future<void> foo() async {
  throw Exception('FooException');
}

您可以使用try-catch块或在Future上使用catchError,因为两者的功能相同。

  • 使用try-catch

try {
  await foo();
} on Exception catch (e) {
  print(e); // Only catches an exception of type `Exception`.
} catch (e) {
  print(e); // Catches all types of `Exception` and `Error`.
}
  • 使用 catchError

    await foo().catchError(print);
    

  • 2
    我在查找答案时来到这个页面,希望它能帮到我:https://dev59.com/kFQJ5IYBdhLWcg3wIyZW#57736915 基本上,我只是想从一个方法中捕获错误消息,但是我在调用时出现了问题。
    throw Exception("message")
    

    在“catchError”中,我得到的是“Exception: message”,而不是“message”。

    catchError(
      (error) => print(error)
    );
    

    在上面的参考中,返回值已经被固定。


    1
    Future < User > userLogin(email, password) async { try {
      Map body = {
        'username': email,
        'password': password
      };
      http.Response response = await http.post(apiUrl, body: body);
      final responseBody = json.decode(response.body);
      final statusCode = response.statusCode;
      if (statusCode != HTTP_200_OK || responseBody == null) {
        throw new FetchDataException(
          "An error occured : [Status Code : $statusCode]");
       }
      return new User.fromMap(responseBody); }
       catch (e){
        print(e.toString());
    }
    

    0
    你也可以像下面这样抛出异常。
     Future.error('Location permissions are denied');
    

    更重要的是,有时候你可能会遇到一种情况,你想对某些异常情况采取行动。
    例如:
      _getCurrentLocation() async {
        try {
          LocationPermission permission = await Geolocator.checkPermission();
          if (permission == LocationPermission.denied) {
            permission = await Geolocator.requestPermission();
            if (permission == LocationPermission.denied) {
              throw Exception("Location permissions are denied");
              //Future.error('Location permissions are denied');
            }
          }
    
          if (permission == LocationPermission.deniedForever) {
            throw Exception("Location permissions permanently denied.");
            //Future.error('Location permissions permanently denied.');
          }
    
          Position pos = await Geolocator.getCurrentPosition();
          _currentPosition = LatLng(pos.latitude, pos.longitude);
        } on Exception catch (e) {
          String message = e.toString();
          if (message == "Location permissions are denied") {
            print("Action on denied location");
            return;
          }
          if (message == "Location permissions permanently denied.") {
            print("Action on permanently denied location");
            return;
          }
    
        }
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接