Node.js 在nodeJS中引发异常与错误对象

Node.js 在nodeJS中引发异常与错误对象,node.js,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

我正在尝试在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.如果我在这里抛出自定义异常,那么我担心节点是单线程的,并且创建错误上下文非常昂贵。

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

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

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

以下是我的总体方案:

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

如果存在预期的错误返回值,例如“用户名已被采用”或“用户名包含无效字符”,这些值不是编程错误,但只是指示为什么要执行给定操作(可能包含用户数据)如果未完成,则我将从将此信息传递给调用方的函数中创建返回值

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

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

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

在您的具体情况下:

function dateCompare(date1,operator,date2)

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

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

我们如何处理它,使它既易于使用,又不太容易使用 贵吗

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

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

请参见上面的描述

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