NodeJS 中抛出异常与错误对象

Krr*_*Raj 5 node.js

我正在尝试在 nodeJS 中实现一个实用程序库,我可以在不同的项目中使用它。我对如何正确处理错误感到困惑。
例如假设我有一个函数

function dateCompare(date1,operator,date2) // it can take either a date object or valid date string.
Run Code Online (Sandbox Code Playgroud)

现在假设提供了无效的输入 -
1.我可以像异步逻辑一样在结果中返回错误 - {error:true,result:""},但这会阻止我将我的函数用作 2.if((date1,'eq',date2) || (date3,'l3',date4)

如果我在这里抛出自定义异常,那么恐怕节点是单线程的并且创建错误上下文非常昂贵。

我们如何处理它既易于使用又不太昂贵?

在什么情况下抛出异常会更合适,即使代价太高?一些实际用例会非常有帮助。

jfr*_*d00 4

对于这样的问题没有“正确”的答案。有多种不同的哲学,您必须决定哪一种对您或您的环境最有意义。

这是我的总体方案:

如果您检测到严重的编程错误,例如函数的必需参数丢失或类型错误,那么我更愿意抛出异常并在异常消息中准确说明错误所在。开发人员第一次运行此代码时应该会看到这一点,然后他们应该知道需要立即更正其代码。这里的总体想法是,您希望开发人员立即看到他们的错误,而抛出异常通常是最快的方法,并且您可以在异常中放置有用的消息。

如果存在预期的错误返回值,例如“用户名已被占用”或“用户名包含无效字符”,这些值不是编程错误,而只是指示给定操作(可能包含用户数据)未完成的原因,则我将从函数中制作返回值,将该信息传达给调用者。

如果您的函数需要返回结果或错误,那么您必须根据具体情况决定是否可以轻松得出一系列易于检测到与成功返回值分开的错误值。例如,Array.prototype.indexOf()返回负值以指示未找到该值或返回零或正数以指示它正在返回索引。这些范围是完全独立的,因此很容易编写测试来区分它们。

抛出异常的另一个原因是,您的代码可能会在以下情况下使用:让异常向上传播多个调用级别或块级别比手动编写代码来传播错误更简单。这是一把双刃剑。虽然有时让异常传播非常有用,但有时您实际上需要了解并处理每个级别的异常,以便在错误情况下正确清理(释放资源等...),因此您不能让反正它会自动上升。

如果这样的区别对于函数的代码或调用它的开发人员来说都不容易做到,那么有时返回一个具有多个属性的对象是有意义的,其中一个是错误属性,另一个是错误属性。其中 是一个值。

在您的具体情况下:

function dateCompare(date1,operator,date2)
Run Code Online (Sandbox Code Playgroud)

if (dateCompare(date1,'eq',date2) || dateCompare(date3,'l3',date4))
Run Code Online (Sandbox Code Playgroud)

如果函数只返回一个布尔值并抛出日期值或运算符无效的异常,那肯定会很方便。这是否是一个好的设计决策在一定程度上取决于它的使用方式。如果您处于紧密循环中,对大量值运行此操作,其中许多值的格式错误并且会引发此类异常,并且在这种情况下性能很重要,那么最好返回上述对象并改变你编写调用代码的方式。

但是,如果格式失败不是常规的预期情况,或者您只执行一次,或者甚至不会注意到异常与返回值的性能差异(通常是这种情况),则抛出异常- 这是一种处理无效输入的干净方法,不会污染函数的预期用例。

我们该如何处理它,既方便使用又不太昂贵?

如果这不是通常预期的情况,那么在错误输入时引发异常并不昂贵。另外,除非此代码处于某种紧密循环中并被多次调用,否则您不太可能注意到返回值和引发/捕获的异常之间的差异。因此,我建议您进行编码以使预期情况更易于编码,并针对意外情况使用异常。然后,您预期的代码路径不会走异常路线。换句话说,异常实际上是正常的“异常”。

在什么情况下抛出异常会更合适,即使成本太高?

请参阅上面的描述。