【问题标题】:Dart : Make reusable try catch block for error handlingDart:为错误处理制作可重用的 try catch 块
【发布时间】:2020-04-26 05:20:07
【问题描述】:

我有一个简单的函数登录请求到服务器,在这个函数中我有一些错误处理。

示例源代码

try {
      final response = await http.post(
        '${appConfig.baseApiUrl}/${appConfig.userController}/loginUser',
        headers: appConfig.headersApi,
        body: {
          "username": username,
          "password": password,
        },
      );
      final Map<String, dynamic> responseJson = json.decode(response.body);
      if (responseJson["status"] == "ok") {
        List userList = responseJson['data'];
        List<UserModel> result = userList.map((e) => UserModel.fromJson(e)).toList();
        return result;
      } else {
        throw CustomError(responseJson['message']);
      }
    } on SocketException catch (_) {
      return Future.error(ConstText.NO_CONNECTION);
    } on TimeoutException catch (_) {
      return Future.error(ConstText.TIMEOUT_EXCEPTION);
    } on FormatException catch (_) {
      return Future.error(ConstText.FORMAT_EXCEPTION);
    } catch (e) {
      return Future.error(e.toString());
    }
  }

在上面的源代码中,我有 4 个处理错误,例如 SocketException、TimeoutException、FormatException 和 UnknownException。这个函数工作正常,但如果我为请求服务器创建另一个函数,我应该再次重复错误处理。 我的问题是,有可能使错误处理可重用吗?我想要这样的东西。

可重复使用的 Try Catch 示例

requestServer(yourRequestServer) async{
  try{
    return yourRequestServer;
  }on SocketException catch (_) {
      return Future.error(ConstText.NO_CONNECTION);
    } on TimeoutException catch (_) {
      return Future.error(ConstText.TIMEOUT_EXCEPTION);
    } on FormatException catch (_) {
      return Future.error(ConstText.FORMAT_EXCEPTION);
    } catch (e) {
      return Future.error(e.toString());
    }
}

如何使用它

Future<String> testLogin(String username,String password)async{
requestServer({
final response = await http.post(
        '${appConfig.baseApiUrl}/${appConfig.userController}/loginUser',
        headers: appConfig.headersApi,
        body: {
          "username": username,
          "password": password,
        },
      );
      final Map<String, dynamic> responseJson = json.decode(response.body);
      if (responseJson["status"] == "ok") {
        List userList = responseJson['data'];
        List<UserModel> result = userList.map((e) => UserModel.fromJson(e)).toList();
        return result;
      } else {
        throw CustomError(responseJson['message']);
      }
});
}

或者,如果您有其他建议,我真的很感激。 谢谢。

【问题讨论】:

    标签: dart


    【解决方案1】:

    重用代码始终是弄清楚要保留什么以及要抽象出什么。 在您的情况下,您希望重用 catch 子句。 您要抽象的是try 子句的主体,它似乎包含一些异步代码。 由于您是对代码进行抽象,因此您需要传入一个 函数。这是将代码变成参数值的唯一方法。

    所以你需要这样的东西:

    Future<T> requestServer(FutureOr<T> computation()) {
      try {
        return await computation();
      } on SocketException catch (_) {
        throw ConstText.NO_CONNECTION;
      } on TimeoutException catch (_) {
        throw ConstText.TIMEOUT_EXCEPTION;
      } on FormatException catch (_) {
        throw ConstText.FORMAT_EXCEPTION;
      } catch (e) {
        throw e.toString();
      }
    }
    

    然后您可以将其用作:

    var result = await requestServer(() {
       final response = await http.post(...
       ...
         return result;
       ...
    });
    

    我将return Future.error(someString); 更改为throw someString,因为它是一样的,而且后者更具可读性。您在这里抛出 strings,而不是异常或错误对象。这是一个大胆的举动,但只要你是再次抓住他们的人,这是合理的。对于其他人来说,这不是一个很好的 API。

    【讨论】:

    • 在对您的代码稍加改进后,例如创建通用类以提高可重用性,它工作正常。谢谢 ! i.stack.imgur.com/IB0pf.png
    • @Irn 但是我能问你一个问题吗?我在futurebuilder中实现了这个功能,但是futurebuilder无法捕捉到这个make app crash的错误。
    • 我对@9​​87654329@ 了解不多,但我猜它需要将来 包含错误。因此,您必须以某种方式处理错误,而不仅仅是再次抛出它。也许将结果包装在一个 Result 中,它可以包含一个值或错误,但它本身只是一个值。
    猜你喜欢
    • 2022-06-16
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 1970-01-01
    • 1970-01-01
    • 2022-12-20
    • 2010-09-12
    • 2012-08-25
    相关资源
    最近更新 更多