flutter - 在 Dart 中为无效参数抛出异常(例如登录)?

标签 flutter dart

我在 Dart 程序中有一个异步函数 signIn,它接受 usernamepassword 字符串参数。该函数调用远程服务器,在用户名和/或密码丢失或不正确的情况下,服务器使用 session token 或验证消息进行响应。

目前我已经通过回调实现了这一点。服务器响应后调用适当的回调。不需要 await

signIn(username, password, onSuccess, onFailure);

随着我对 Dart 的了解越来越多,我觉得上面的内容并不是真正的 Dart 做事方式。我应该将 awaittrycatch 结合使用吗?像下面这样的东西?

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.
}

可能是无效的登录凭据。处理它们是正常的程序流程。我被教导永远不要对常规的、预期的程序流使用 try/catch。似乎 Dart 语言鼓励为此使用异常处理,尤其是与 await 结合使用。

来自 Error class documentation [强调我的。]

If the conditions are not detectable before calling a function, the called function should not throw an Error. It may still throw a value, but the caller will have to catch the thrown value, effectively making it an alternative result rather than an error. The thrown object can choose to implement Exception to document that it represents an exceptional, but not erroneous, occurrence, but it has no other effect than documentation.

实现这个的最好的 Dart 方法是什么?

最佳答案

错误与异常

您链接的文档基本上说 Error class不应该用于您定义为“常规的、预期的程序流程”,而是Exception应该。这也意味着在 Dart 中鼓励使用 try-catch 来解决这些情况。

根据文档,错误 应该用于“程序员本应避免的程序失败”,即意外 em>程序流程。但是,Exception 是“旨在向用户传达有关故障的信息,以便可以通过编程方式解决错误”,即 预期程序流程

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

Creating instances of Exception directly with new Exception("message") is discouraged, and only included as a temporary measure during development, until the actual exceptions used by a library are done.

例子

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和无效的密码(可能不是你想要做的,它应该只是解释这个概念)。

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

当对 catch 语句使用 on 时,您冒着无法捕捉到其他类型异常的风险,这些异常随后将被抛出。如果你想防止这种情况发生,你可以为通用异常设置另一个 block ,即 on Exception 或者在末尾有一个通用的 catch block (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});
}

关于flutter - 在 Dart 中为无效参数抛出异常(例如登录)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57000995/

相关文章:

ios - 如何让 setInitialRoute 在不同的 View 上启动我的 Flutter iOS 应用程序?

Flutter TextField LabelText 中心

flutter - 如何将两个列表合并为一个具有特定顺序的列表?

xcode - Flutter 生成的 ios 文件版本控制

android - 如何在 Flutter 上选择唯一的前置摄像头

flutter - 我在 Flutter SDK 中使用哪个 channel ?

flutter - 添加多张图片

class - 如何在Flutter中从另一个类访问一个类方法?

generics - 在 Dart 中使用泛型与返回动态

dart - 使用AngularDart的Facebook身份验证