【问题标题】:Handling exception HTTP request flutter处理异常 HTTP 请求颤动
【发布时间】:2020-06-24 04:50:26
【问题描述】:

我想处理带有一些错误消息的 http 请求抖动,但我在这里遇到了很多错误。我只是根据建议做的,但它对我不起作用。请任何人帮助我 这是我调用 API 的函数

getData(data, apiUrl) async {
    var tempUrl = _url + apiUrl + await _getToken();
    Uri uri = Uri.parse(tempUrl);
    var fullUrl = uri.replace(queryParameters: data);
    var res;
    try {
      var response = await http.get(fullUrl, headers: _setHeaders()).timeout(
          const Duration(seconds: 60));
      print(response.statusCode);
      if (response.statusCode != 200) {
        res = {
          "success": false,
          "status": response.statusCode,
          "message": _returnResponse(response)
        };
      }
      else {
        res = response;
      }
    }
    on SocketException {
      throw FetchDataException('No Internet connection');
    }
    on TimeoutException catch (e) {
      res = {
        "success": false,
        "status": response.statusCode,
        "message": "Connection timeout"
      };
    } on Error catch (e) {
      print('Error: $e');
    }

    return res;
  }

这是我对除 200 以外的其他人的回复

dynamic _returnResponse(http.Response response) {
    switch (response.statusCode) {
      case 400:
        throw BadRequestException(response.body.toString());
      case 401:
      case 403:
        throw UnauthorisedException(response.body.toString());
      case 500:
      default:
        throw FetchDataException(
            'Error occured while Communication with Server with StatusCode : ${response
                .statusCode}');
    }
  }

这是我从 StackOverflow 和其他论坛获得的 app_exception.dart

class AppException implements Exception {
  final _message;
  final _prefix;

  AppException([this._message, this._prefix]);

  String toString() {
    return "$_prefix$_message";
  }
}

class FetchDataException extends AppException {
  FetchDataException([String message])
      : super(message, "Error During Communication: ");
}

class BadRequestException extends AppException {
  BadRequestException([message]) : super(message, "Invalid Request: ");
}

class UnauthorisedException extends AppException {
  UnauthorisedException([message]) : super(message, "Unauthorised: ");
}

class InvalidInputException extends AppException {
  InvalidInputException([String message]) : super(message, "Invalid Input: ");
}

我尝试了很多建议,但根本没有用

我收到了这个错误

错误:“SocketException”不是一种类型。 在 SocketException { ^^^^^^^^^^^^^^^

错误:“TimeoutException”不是一种类型。 在 TimeoutException 上捕获 (e) { ^^^^^^^^^^^^^^^^

【问题讨论】:

    标签: flutter http dart exception httprequest


    【解决方案1】:

    这里是一步一步的过程

    首先添加http: ^0.13.4,然后按照以下步骤操作

    1) 创建 API 基础助手类
    为了在我们的远程服务器和应用程序之间进行通信,我们使用各种 API,这些 API 需要某种类型的 HTTP 方法来执行。所以我们首先要创建一个基础 API 帮助类,它将帮助我们与服务器进行通信。

    import 'CustomException.dart';
    import 'package:http/http.dart' as http;
    import 'dart:io';
    import 'dart:convert';
    import 'dart:async';
    import 'package:connectivity/connectivity.dart';
    
    class APIManager {
    
      Future<dynamic> postAPICall(String url, Map param) async {
        print("Calling API: $url");
        print("Calling parameters: $param");
    
        var responseJson;
        try {
          final response =  await http.post(url,
          body: param);
          responseJson = _response(response);
        } on SocketException {
          throw FetchDataException('No Internet connection');
        }
        return responseJson;
      }
    
      dynamic _response(http.Response response) {
        switch (response.statusCode) {
          case 200:
            var responseJson = json.decode(response.body.toString());
            return responseJson;
          case 400:
            throw BadRequestException(response.body.toString());
          case 401:
          case 403:
            throw UnauthorisedException(response.body.toString());
          case 500:
          default:
            throw FetchDataException(
              'Error occured while Communication with Server with StatusCode: ${response.statusCode}');
        }
      }
    }
    

    2) 创建自定义异常类

    执行时的 HTTP 请求可以根据其状态返回各种类型的状态代码。如果请求失败,我们不希望我们的应用程序行为异常,因此我们将在我们的应用程序中处理其中的大部分。为此,我们将创建我们可以根据响应状态代码抛出的自定义应用程序异常。

    class CustomException implements Exception {
      final _message;
      final _prefix;
    
      CustomException([this._message, this._prefix]);
    
      String toString() {
      return "$_prefix$_message";
      }
    }
    
    class FetchDataException extends CustomException {
      FetchDataException([String message])
      : super(message, "Error During Communication: ");
    }
    
    class BadRequestException extends CustomException {
      BadRequestException([message]) : super(message, "Invalid Request: ");
    }
    
    class UnauthorisedException extends CustomException {
      UnauthorisedException([message]) : super(message, "Unauthorised: ");
    }
    
    class InvalidInputException extends CustomException {
      InvalidInputException([String message]) : super(message, "Invalid Input: ");
    }
    

    3) 创建一个从 API 获取数据的方法

    调用 API:- 用于从 API 获取数据

    void signIn(Map param)  {
      setState(() {
        _isLoading = true;
      });
      apiManager.postAPICall(BASE_URL + user_login, param).then((value) {
        var status_code = value["statuscode"];
        if (status_code == 200) {
          var userData = value["user_data"];
          Navigator.push(context, PageTransition(type: 
          PageTransitionType.rightToLeftWithFade, child: HouseholderHomeScreen()));
    
          setState(() {
            _isLoading = false;
          });
        } else {
          setState(() {
            _isLoading = false;
          });
          _scaffoldKey.currentState.showSnackBar(
              SnackBar(
                content: new Text(value["msg"]),
                backgroundColor: Colors.red,
                duration: new Duration(seconds: 2),
              )
          );
        }
     }, onError: (error) {
        setState(() {
          _isLoading = false;
        });
        print("Error == $error");
        _scaffoldKey.currentState.showSnackBar(
          SnackBar(
            content: new Text('Something went wrong..'),
            duration: new Duration(seconds: 2),
          )
        );
        print(error);
      });
    }
    

    【讨论】:

    • 第一步,你应该在调用API之前解析你的url,await http.post(Uri.parse(url), body: param);
    【解决方案2】:

    我使用了 dio 包。这比我做的更容易,错误更少

    https://pub.dev/packages/dio

    【讨论】:

    • 很有前途的库,但对我来说效果不佳。在调用已经被 try/catch 块包围的情况下抛出未处理的异常。而且这个问题已经在问题跟踪器上打开了几个月,没有任何回应
    【解决方案3】:

    如果发生的错误发生在 SocketException 和 Timeout 异常上,请确保您已分别在该文件中导入了 dart.iodart.async。根据您的代码,我能够成功运行它,但您可以参考 Paresh Mangukiya 的answer 一步一步地了解或参考here 以进一步说明如何使用自定义错误响应处理网络调用和异常颤抖。

    【讨论】:

      猜你喜欢
      • 2020-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-12
      • 2014-08-05
      • 2019-10-04
      相关资源
      最近更新 更多