在Node.js中暴露和组合错误的最佳方法是什么?

Ase*_*ore 6 javascript error-handling node.js

我正在编写一个与REST API对话的模块,并且由于REST API提供了良好的语义错误响应(例如403与503),我想将这些语义错误传达给调用者.

(编辑:我的意思是,调用者应该能够以编程方式理解错误的原因并采取相应的行动,例如显示相应的UI.)

对我来说最好的方法是什么?

  1. 创建我自己的Error那些语义,子类例如mymodule.ForbiddenError,mymodule.ServiceUnavailableError?然后,调用者将检查instanceof以获得语义.这在静态类型语言(如C#和Java)中最为常见.

  2. mymoduleCode属性添加到标准Error实例,使用'Forbidden'或等语义字符串'ServiceUnavailable'.Node.js本身就是这样做的,例如code: 'ECONNREFUSED'.

  3. 还有其他方法吗?

==

我现在正在编写另一个模块,它包装了第一个模块.我不想直接公开内部模块的错误,但为了可调试性,编写/包装它们会很好.

对我来说,最好的方法是什么呢?

  1. 将一个internalError属性添加到Error引用内部模块Error实例的实例中.C#和Java再次这样做.(Exception#InnerException/Throwable#cause)

  2. 还有其他方法吗?

但是,我见过的大多数工具只显示实例的stack属性Error,因此在这些情况下这些数据会丢失.是否存在已经存在的典型/传统方式?

oth*_*m23 6

您描述的用例是Node现在无法满足的用例.由于使用的惯例,它们往往是以下的混合物:

  1. 创建简单派生自Error构造函数的新错误类型.主要用于创建高级错误类别.您可以使用instanceof错误类型之间discriminiate,但并不觉得很JavaScripty.
  2. 创建Java样式的Error子类型,将另一个错误作为构造函数参数,然后将其包装起来.如果您使子类型公开API,那么您基本上使用多态而不是直接分派来根据类型处理错误.
  3. 通过Error构造函数创建语义上有用的错误消息.这是我倾向于使用很多的模式.
  4. 将属性附加到错误,这也是非常常见的.
  5. 创建一个解耦的错误处理API,可以从错误发生的任何地方调用它.这为您提供了一个集中所有代码的地方,这些代码可以确定您遇到的错误类型以及应该如何处理错误,并注入处理错误所需的任何依赖项.

这里真正的问题是这些都是临时机制,我不会说它们中的任何一个已达到临界质量.我认为这部分是由于异步性和JavaScript的结合使得很难正确并完全处理错误,因此建议通常在捕获有关错误的信息后关闭整个过程.

这并不能很好地处理预期的错误,但我认为大多数错误都是由框架捕获的(例如Express错误处理程序)或者放入Node回调约定.简而言之,我认为这里有空间来定义一些惯例,因为最先进的技术并不是那么巧妙.


Ase*_*ore 5

发现这篇很棒的文章谈到这个:

http://www.joyent.com/developers/node/design/errors

这里粘贴太多,但在"具体建议"下,第2至5项解决了这个问题:

  1. 清楚你的功能是做什么的.
  2. Error对所有错误使用对象(或子类),并实现Error合同.
  3. 使用Error的name属性以编程方式区分错误.
  4. Error使用解释详细信息的属性扩充对象
  5. 如果将较低级别的错误传递给调用者,请考虑将其包装.

特别是,该文章链接到此模块以包装/撰写错误:

https://github.com/joyent/node-verror

我不确定我是否必须遵循这些确切的约定 - 例如,我看到了具有应用程序域code属性的价值 - 但原则非常有用.