Dart是否为无效参数(例如登录)抛出异常? [英] Throwing Exceptions in Dart for Invalid Parameters (e.g. Sign In)?

查看:89
本文介绍了Dart是否为无效参数(例如登录)抛出异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Dart程序中有一个异步函数signIn,该函数需要usernamepassword字符串参数.该函数调用远程服务器,并且在用户名和/或密码丢失或不正确的情况下,服务器将使用会话令牌或验证消息进行响应.

I have an async function signIn in a Dart program that takes username and password string arguments. The function calls a remote server and the server responds with a session token or validation messages in the case of missing or incorrect username and/or password.

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

Currently I have this implemented with callbacks. The appropriate callback is called after the server responds. No need for await.

signIn(username, password, onSuccess, onFailure);

我对Dart的了解越多,我觉得以上内容并不是Dart的实际工作方式.我应该结合使用awaittrycatch吗?类似于以下内容?

The more I read about Dart, I feel like the above isn't really the Dart way of doing things. Should I be using await combined with try and catch? Something like the following?

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结合使用.

Invalid sign in credentials are likely. Handling them is normal program flow. I was taught never to use try/catch for regular, expected program flow. It seems that the Dart language is encouraging using exception handling for this especially in combination with await.

来自错误类文档 [强调我的.]

From Error class documentation [Emphasis mine.]

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

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的最佳方式是什么?

What's the best most Dart way to implement this?

推荐答案

错误与异常

您链接的文档实际上表示 Error不应用于定义为正常的预期程序流" 的内容,而应用于

Error vs. Exception

The documentation you linked essentially says that the Error class should not be used for what you define as "regular, expected program flow" but Exception should. This also means that using try-catch for addressing these kinds of cases is encouraged in Dart.

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

From the documentation, Error's should be used for "a program failure that the programmer should have avoided", i.e. unexpected program flow. However, Exception's are "intended to convey information to the user about a failure, so that the error can be addressed programmatically", i.e. expected program flow.

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

In order to implement exceptions, you will have to extend Exception and create your own exception class. Dart enforces this by not providing access to the message passed to a regular Exception.

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

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和无效的password(可能不是您想做的,它应该只是解释一下)概念).

I created InvalidCredentialsException to handle invalid credentials passed to signIn. For the message (you can call it whatever you want), I simply used an enum to distinguish between an invalid username and an invalid password (probably not what you would want to do, it should just explain the concept).

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

When handling it using try-catch, you can create different catch-blocks for different types. In my example, I use on InvalidCredentialsException for responding to the expected exception in your program flow and another one on Error for unexpected failures.

catch语句中使用on时,冒着无法捕获其他类型异常的风险,然后会抛出该异常.如果要防止这种情况,可以为通用异常添加另一个块,即on Exception,或者在末尾仅包含一个通用catch块(catch (e)).

When using on for catch-statements, you run the risk of not catching other types of exceptions, which will then be thrown. If you want to prevent that, you can either have another block for generic exceptions, i.e. on Exception or just have a generic catch-block at the end (catch (e)).

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

You might want to override toString in your exception class if you want to be able to print out your exception.

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

Additionally, you can obviously transport as much information with your exception as you like, e.g. (modified from the above code):

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

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

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

这篇关于Dart是否为无效参数(例如登录)抛出异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆