Dart是否为无效参数(例如登录)抛出异常?

时间:2019-07-12 06:02:34

标签: flutter dart

我在Dart程序中有一个异步函数signIn,该函数带有usernamepassword字符串参数。该函数调用远程服务器,如果用户名和/或密码丢失或不正确,则服务器将使用会话令牌或验证消息进行响应。

目前,我已通过回调实现了此功能。服务器响应后,将调用适当的回调。不需要await

signIn(username, password, onSuccess, onFailure);

我对Dart的了解越多,我觉得以上内容并不是Dart的实际工作方式。我应该结合使用awaittry的{​​{1}}吗?像下面这样?

catch

可能是无效的登录凭据。处理它们是正常的程序流程。我被教导永远不要对常规的预期程序流使用try / catch。似乎Dart语言鼓励使用异常处理,尤其是与try { sessionToken = await signIn(username, password); // navigate from the sign in screen to the home screen. } on InvalidParams catch (e) { // e contains the server's validation messages // show them to the user. } 结合使用。

来自Error class documentation [强调我。]

  

如果在调用函数之前无法检测到条件,则   调用的函数不应引发错误。它可能仍会抛出一个值,   但呼叫者将必须捕获抛出的值,有效地使   它是替代结果,而不是错误。抛出的物体可以   选择实施Exception以记录它表示一个   异常但不是错误的发生,但是没有其他影响   比文档更重要。

实现Dart的最佳方式是什么?

1 个答案:

答案 0 :(得分:1)

错误与异常

您链接的文档从本质上说,Error class不应用于定义为“正常的预期程序流” 的内容,而应使用Exception。这也意味着在Dart中鼓励使用try-catch处理此类情况。

从文档中,应将 Error 用于“程序员应避免的程序故障”,即 意外 < / strong> 程序流程。但是, Exception 是“旨在向用户传达有关故障的信息,以便可以通过编程方式解决错误”,即 expected 程序流程

为了实现异常,您将必须扩展Exception并创建自己的异常类。 Dart通过不提供对传递到常规Exception的消息的访问来实施此操作。

  

不建议直接使用new Exception("message")创建Exception的实例,并且仅在开发过程中将其作为临时措施包括在内,直到完成库使用的实际异常为止。

示例

enum InvalidCredentials { username, password }

class InvalidCredentialsException implements Exception {
  final InvalidCredentials message;

  const InvalidCredentialsException({this.message});
}

function() {
  try {
    await signIn(username, password);
  } on InvalidCredentialsException catch (e) {
    switch (e.message) {
      case InvalidCredential.username:
        // Handle invalid username.
        break;
      case InvalidCredential.password:
        // Handle invalid password.
        break;
    }
  } on Error catch (e) {
    print(e);
  } catch (e) {
    // Handle all other exceptions.
  }
}

我创建了InvalidCredentialsException来处理传递给signIn的无效凭证。对于message(您可以随心所欲地调用它),我只是使用enum来区分无效的username和无效的password(可能不是您想要的)要这样做,应该只解释一下这个概念。

使用try-catch处理它时,可以为不同类型创建不同的catch块。在我的示例中,我使用on InvalidCredentialsException响应程序流中的 expected 异常,并使用另一个on Error响应 expected 失败。

on语句中使用catch时,您冒着无法捕获其他类型异常的风险,然后将其抛出。如果要防止这种情况,则可以为通用异常设置另一个块,即on Exception,或者在结尾(catch)后面仅具有通用catch (e)块。

如果您希望能够打印出异常,则可能希望覆盖异常类中的toString

此外,您显然可以根据自己的意愿传输尽可能多的信息,例如(根据上面的代码修改):

// ...
throw InvalidCredentialsException(cause: InvalidCredentials.password, message: password);
// ...

class InvalidCredentialsException implements Exception {
  final InvalidCredentials cause;
  final String message;

  const InvalidCredentialsException({this.cause, this.message});
}