我正在编写一个与REST API对话的模块,并且由于REST API提供了良好的语义错误响应(例如403与503),我想将这些语义错误传达给调用者。
(编辑:我的意思是,调用者应该能够以编程方式理解错误的原因并采取相应的行动,例如显示相应的UI。)
对我来说最好的方法是什么?
为这些语义创建我自己的Error
子类,例如: mymodule.ForbiddenError
,mymodule.ServiceUnavailableError
?然后,呼叫者将检查instanceof
以获得语义。这在C#和Java等静态类型语言中最为常见。
添加例如标准mymoduleCode
实例的Error
属性,具有'Forbidden'
或'ServiceUnavailable'
等语义字符串。 Node.js本身就是这样做的,例如code: 'ECONNREFUSED'
。
其他方式?
==
我现在正在编写另一个模块,它包装了第一个模块。我不想直接暴露内部模块的错误,但为了可调试性,编写/包装它们会很好。
对我来说,最好的方法是什么呢?
添加例如引用内部模块internalError
实例的Error
个实例的Error
属性。 C#和Java再次这样做。 (Exception#InnerException / Throwable#cause)
其他方式?
我看到的大多数工具只显示stack
个实例的Error
属性,因此在这些情况下这些数据会丢失。是否存在已经存在的典型/传统方式?
答案 0 :(得分:6)
您描述的用例现在肯定是Node未充分利用的用例。由于使用的惯例,它们往往是以下的混合物:
instanceof
来区分错误类型,但这并不是非常简单的JavaScripty。这里真正的问题是这些都是临时机制,我不会说它们中的任何一个已达到临界质量。我认为这部分是由于异步性和JavaScript的结合使得很难正确并完全处理错误,因此建议通常在捕获有关错误的信息后关闭整个过程。
这在处理预期错误方面做得不好,但我认为大多数错误都是由框架捕获的(例如Express错误处理程序)或者放入Node回调约定。简而言之,我认为这里有空间来定义一些惯例,因为最先进的技术并不是那么巧妙。
答案 1 :(得分:5)
发现这篇很棒的文章谈论这个:
http://www.joyent.com/developers/node/design/errors
此处粘贴太多,但在“特定建议”下,第2项至第5项解决了这个问题:
- 明确你的功能。
- 对所有错误使用
Error
个对象(或子类),并实施Error
合同。- 使用错误的
name
属性以编程方式区分错误。- 使用详细说明
的属性扩充Error
对象- 如果您向调用者传递了较低级别的错误,请考虑将其换行。
醇>
特别是,该文章链接到此模块以包装/撰写错误:
https://github.com/joyent/node-verror
我不确定我是否必须遵循这些完全约定 - 例如我认为拥有应用程序域code
属性很有价值 - 但原则非常有用。
答案 2 :(得分:1)
编辑我是StackOverflow 和 Node.js的新手。别人应该回答这个问题! : - )
如果您来自Java / C#欢迎使用JavaScript!我从未见过Node.js库使用instanceof
来检查错误类型,但正如你所说的那样在静态语言中很常见。
话虽如此,通常只会创建新错误,并使用NodeJS的回调样式(err, response)
进行回调。
我总是遇到来自其他模块的错误消息,知道它们来自何处以及创建包装错误消息是有帮助的,这些消息可能隐藏它实际上在我身上死亡的地方(我需要更多的东西来挖掘)。
创建一个可以处理字符串的休息错误消息(或者在您的情况下,响应无效)的函数的示例:
function myFunction(callback) {
callRestAPI('http://someApi.com/request', function(errorString, jsonResponse) {
if (errorString) {
callback(new Error("something wrong in myFunction! " + errorString));
} else {
callback(null, JSON.parse(jsonResponse));
}
});
}
在您的情况下,“errorString”检查基本上是响应(403/503),您可以将错误消息的结构设置为new Error( ... )
,例如new Error('Failed! Got response 403!')
我可能错过了你的观点,也许别人可以更彻底。
重新阅读之后,你能发布你正在包装的模块吗?是节点请求吗?
答案 3 :(得分:1)
我对节点也很陌生,所以请稍等一下,但我会选择你的#2选项,添加一个属性。 (This is also suggested here)
这几乎是你最初的#2选项。如果错误处理程序只记录堆栈,而不是错误本身,那就是他们的错误。 :-)(严肃的,不知道你怎么做得更好)
答案 4 :(得分:0)
我只需将httpCode
属性附加到错误对象即可。 KISS