在nodeJS中抛出异常与错误对象

时间:2016-07-14 03:31:16

标签: node.js

我正在尝试在nodeJS中实现一个可以在不同项目中使用的实用程序库。我坚持如何正确处理错误。
例如假设我有一个功能

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

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

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

我们如何处理它以便它既易于使用又不是非常昂贵?

在什么情况下抛出例外更合适,即使它太贵了?一些实际的用例非常有用。

1 个答案:

答案 0 :(得分:2)

对于这样的问题,没有“正确”的答案。有各种不同的哲学,你必须决定哪一个对你或你的背景最有意义。

这是我的一般方案:

如果你发现一个严重的编程错误,例如函数的必需参数丢失或者类型错误,那么我更喜欢抛出一个异常并在异常msg中拼出错误的错误。开发人员第一次运行此代码时应该会看到这一点,然后他们应该知道他们需要立即纠正他们的代码。这里的一般想法是,您希望开发人员立即看到他们的错误,抛出异常通常是最快的方法,您可以在异常中添加有用的消息。

如果存在预期的错误返回值,例如“用户名已被占用”或“用户名包含无效字符”,这些错误不是编程错误,而只是指示为什么给定操作(可能包含用户数据)没有完成后,我会从将此信息传达给调用者的函数中创建返回值。

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

抛出异常的另一个原因是你的代码很可能被用在这样一种情况下:让异常传播几个调用级别或块级别而不是手动编写代码来传播错误。这是一把双刃剑。虽然有时让异常传播非常有用,但有时你实际上需要了解并处理每个级别的异常,以便在错误条件下正确清理(释放资源等等),这样你就不能让无论如何,它可能会自动升级。

如果对于函数的代码或将调用它的开发人员这样的区别并不简单,那么有时返回一个具有多个属性的对象是有意义的,其中一个属性是错误的财产,另一个是价值。

在您的特定情况下:

function dateCompare(date1,operator,date2)

if (dateCompare(date1,'eq',date2) || dateCompare(date3,'l3',date4))

如果函数只返回一个布尔值并抛出日期值的异常或操作符无效,那肯定会很方便。这是否是一个好的设计决定取决于如何使用它。如果你处于一个紧凑的循环中,在许多值上运行它,其中许多将被严格格式化并且会抛出这样的异常并且在这种情况下性能很重要,那么返回上述对象可能会更好改变你编写调用代码的方式。

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

  

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

如果不是通常预期的情况,那么在输入错误时抛出异常并不昂贵。另外,除非此代码处于某种紧密循环并且多次调用,否则您甚至不会注意到返回值与抛出/捕获异常之间的差异。所以,我建议你编写代码,使预期的案例更容易编码并使用异常来处理意外情况。然后,您的预期代码路径不会成为异常路由。换句话说,例外实际上是正常的“例外”。

  

在什么情况下抛出异常会更合适   即使它太贵了?

参见上面的描述。