在Dart中抛出错误的正确方法

时间:2019-08-20 23:00:34

标签: exception dart error-handling

Dart提供了一个Error类和一个Exception类,用于引发异常。为什么Error构造函数不像Exception构造函数那样接受消息参数?

来自Error class docs

  

程序失败时抛出的错误对象。

     

Error对象代表程序员应该避免的程序故障。

来自Exception class docs

  

异常旨在将有关故障的信息传达给用户,以便可以以编程方式解决错误。它旨在被捕获,并且应包含有用的数据字段。

更早的SO answer引用了一篇帖子,确认了这种区别。

我喜欢这种区别。这就告诉我,我的许多支票都应该抛出Error的实例。

我很高兴将错误类型归为Error,但是我仍然需要报告引起错误的值。为什么Dart使我可以很容易地使用Exception而不是Error来做到这一点?

我意识到我可以通过声明一个应用范围的错误类来解决问题:

class AppError extends Error {
  String message;

  AppError([this.message]);

  String toString() {
    return message == null ? runtimeType : "$runtimeType: $message";
  }
}

ErrorException之间的这种区别让我认为我误解了Error或使用不当。在Dart中引发非用户错误的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

如果有的话,Exception 接收消息是错误的。你应该永远抛出一个普通的 new Exception("message")

ErrorException(或者实际上,任何非 Error 抛出的对象)之间的区别在于 Error 表示编程失败。

您的程序不应抛出 Error 作为正常操作的一部分。您不应捕捉到特定的 Error 并对其做出反应。 (框架可以捕获所有抛出的对象并记录它们以继续运行,但它们不应该专门对单个错误做出反应)。 这意味着使用哪个类来表示错误实际上并不重要。错误的唯一目的是向程序员展示,以便他们可以修复他们的错误。 Dart 有许多有用的 Error 子类,它们涵盖了大多数情况,并确保了错误消息的格式一致。没有什么本质上要求您对越界错误使用 RangeError,它只是一个非常方便的帮助器类,它可以帮助读者了解发生了什么,我们建议您使用它。< /p>

当函数的参数不满足它的额外(非类型)要求(例如,列表必须非空)时,请使用 ArgumentError。 对于数字参数,当数字不在预期范围内时有一个 RangeError。对于用作索引的数字(如 list.operator[] 参数),甚至还有专门的 IndexError。它们都是为了确保您获得一致的错误消息。

如果操作不能立即执行,因为对象不处于支持它的状态,请使用StateError

如果当前对象永远无法执行操作,请使用UnsupportedError

在实践中,StateErrorUnsupportedErrorArgumentError(及其子类)涵盖了用户代码抛出的大部分运行时错误。 简单地抛出一个 Error("message") 比使用其中一个提供的信息要少,而且发明一种新的错误类型很少值得。

另一方面,异常意图被捕获和处理。 这是给调用者的一条消息,与返回值具有相同的重要性,它应该包含足够的信息让调用者捕获函数可能抛出的特定记录异常,以及对特定的异常情况做出反应。 这就是为什么异常至少应该有一个独特的类型,让您可以专门识别和捕获它,并且如果可能,它应该包含处理异常情况所需的任何信息。

以各种 FormatException 函数抛出的 parse 为例。 它特定于操作。它包含可帮助您找出问题所在的可用信息(输入和与错误相关的位置,主要用于向用户展示,因为您无法修复输入。)

答案 1 :(得分:0)

请参见https://github.com/dart-lang/sdk/blob/master/sdk/lib/core/errors.dart

Dart有几个预定义的错误,您可以立即使用。