【问题标题】:Flutter error throw from another class is not caught by the calling function调用函数未捕获来自另一个类的 Flutter 错误
【发布时间】:2020-01-12 08:31:36
【问题描述】:

我在 Flutter 中有一个 this bloc 实现,所以一旦触发 bloc,它将调用这个 apiCall() 函数,如下所示

Future apiCall() async {
    print("calling api now ");
    var future = repository.getList().catchError((err) {
      print("api_bloc:Error is " + err.toString());
      if(err is AuthError){
        print("Auth error");
      }      
    });
  }

这将调用存储库函数repository.getList(),如下所示。

Future<CountyListRoot> getList() async {

      String url = "countyList";
       try{
      final countyListJson = await NetworkUtils.postNoToken(url).catchError((err) {
          print("county list repository is " + err.toString());
          if(err is AuthError){
            print("catch at repository Auth error");
            throw AuthError('Auth Error: ');
          }
      });
      print("countyListJson" + countyListJson.toString());
      return CountyListRoot.fromJson(countyListJson);
      }
      catch(exception){
        if(exception is AuthError){
          print("catch at repository Auth error");
        }
        print("Exception");
      }


  }

在上面它调用 NetworkUtils.postNoToken(url) 来执行实际的发布并捕获并抛出错误。所以按道理它应该被捕获在上面的函数中,但它没有。以下是实际帖子。

static dynamic postNoToken(String url) async {
        var uri = host + '/api/'+ url;

        try {

            final response = await http.post(
                uri,
        headers: {

            );

            final code = response.statusCode;
      print("Network util post reply code:"+code.toString());
      print("Network util post reply response body:"+response.body);
            if(code==401){

                throw AuthError('$code Auth Error: '+parseMessage(response.body));
            }
            else if(code>=500){

                throw UnknownError('$code. Server error: '+parseMessage(response.body));
            }
            else if(code>=400){

                throw Error4xx(' $code Wrong request : '+parseMessage(response.body));
            }


            return response.body;

        } catch (exception) {
            print(exception);

        }
    }

所以在上面的场景中,我特意创建了一个生成的场景

if(code==401){

                throw AuthError('$code Auth Error: '+parseMessage(response.body));
            }

但它没有在存储库功能中捕获或显示。 下面我也创建了模型。

class UnknownError {
  final String message;

  UnknownError(this.message);

}

class DiffError{
  final String message;

  DiffError(this.message);
}

class AuthError {
  final String message;

  AuthError(this.message);
}

class Error4xx {
  final String message;

  Error4xx(this.message);

}

如何解决这个错误捕获和传递,以便我最终可以通过一些快餐栏或相应的弹出窗口显示?

【问题讨论】:

    标签: android flutter error-handling


    【解决方案1】:

    当你捕捉到一个异常时,你需要rethrow 它以便它可以被调用者捕捉到。

    https://dart.dev/guides/language/effective-dart/usage#do-use-rethrow-to-rethrow-a-caught-exception

    因此,如果当前捕获到的异常没有被该特定捕获处理,则应该rethrow

    void misbehave() {
      try {
        dynamic foo = true;
        print(foo++); // Runtime error
      } catch (e) {
        print('misbehave() partially handled ${e.runtimeType}.');
        rethrow; // Allow callers to see the exception.
      }
    }
    
    void main() {
      try {
        misbehave();
      } catch (e) {
        print('main() finished handling ${e.runtimeType}.');
      }
    }
    

    【讨论】:

    • 所以我放置投掷的每个地方都应该用 rethrow 替换是吗?
    • 问题是第一次投掷也没有被抓到,所以在我的情况下如何重新投掷?
    • 不,它应该放在你的 catch 块中。每次你捕获一个异常但不处理它时,你应该重新抛出,以便调用者可以捕获它。我添加了一些示例代码。
    • 我没有得到在我的情况下我抛出的第一个地方是这样 throw AuthError('$code Auth Error: '+parseMessage(response.body));那么如何将其转换为 rethrow 因为我看到 rethrow 必须是 rethrow;以分号结尾
    • 还有另一个问题,这个抛出没有被捕获在异常中,因为我基于我的 http 的返回响应代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 2018-09-22
    • 2021-06-11
    相关资源
    最近更新 更多