Node.js 的错误处理原则 + Express.js 应用程序?
与 Node.js+Express.js 应用程序相比,错误报告/处理的方式似乎有所不同到其他框架。我对它的工作原理的理解是否正确?
A) 通过将错误作为参数接收到回调函数来检测错误。例如:
doSomethingAndRunCallback(function(err) {
if(err) { … }
});
B) 通过调用 next(err) 报告 MIDDLEWARE 中的错误。示例:
handleRequest(req, res, next) {
// An error occurs…
next(err);
}
C) 通过抛出错误来报告 ROUTES 中的错误。示例:
app.get('/home', function(req, res) {
// An error occurs
throw err;
});
D) 通过 app.error() 配置您自己的错误处理程序来处理错误,或者使用通用的 Connect 错误处理程序。示例:
app.error(function(err, req, res, next) {
console.error(err);
res.send('Fail Whale, yo.');
});
这四个原则是 Node.js+Express.js 应用程序中所有错误处理/报告的基础吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Node.js 中的错误处理通常采用 A) 格式。大多数回调返回一个错误对象作为第一个参数或
null
。Express.js 使用中间件,中间件语法使用 B) 和 E)(下面提到)。
如果你问我的话,C)是不好的做法。
您可以轻松地重写上述内容,因为
中间件语法在
get
请求中有效。至于D)
TJ 刚刚确认
app.error
已被弃用,取而代之的是 EE)
任何长度为 4 的中间件 ( 4 个参数)被视为错误中间件。当调用
next(err)
连接时,它会调用基于错误的中间件。Error handling in Node.js is generally of the format A). Most callbacks return an error object as the first argument or
null
.Express.js uses middleware and the middleware syntax uses B) and E) (mentioned below).
C) is bad practice if you ask me.
You can easily rewrite the above as
Middleware syntax is valid in a
get
request.As for D)
TJ just confirmed that
app.error
is deprecated in favor of EE)
Any middleware that has a length of 4 (4 arguments) is considered error middleware. When one calls
next(err)
connect goes and calls error-based middleware.Joyent 的人员就此发布了一份非常有洞察力的最佳实践文档。所有 Node.js 开发人员必读的文章。
People at Joyent have published a really insightful best-practices document on this. A must-read article for any Node.js developer.
为什么是第一个参数?
由于 Node.js 的异步特性,first-parameter-as-err 模式已成为 用户态 Node.js 错误处理。这是因为异步:
因此,使用回调的第一个参数几乎是异步传递错误的唯一明智方法,而不仅仅是抛出错误。
这样做将导致
未处理的异常
,顾名思义,这意味着没有采取任何措施使应用程序摆脱混乱状态。异常,为什么它们存在
然而值得注意的是,实际上 Node.js 的所有部分都是事件发射器,异常的抛出是一个低级事件,可以像所有事件一样处理:
这个可以-但是-不应该采取极端的方式捕获所有错误并创建一个将努力避免崩溃的应用程序。在几乎所有用例中,这都是一个糟糕的想法,因为它会让开发人员不知道应用程序状态中发生了什么,类似于将 main 包装在 try-catch 中。
域 - 对事件进行逻辑分组
作为处理导致应用程序崩溃的异常问题的一部分,域允许例如,开发人员可以采用 Express.js 应用程序,并在发生灾难性故障时尝试明智地关闭连接。
ES6
可能会提到,这将再次改变,因为 ES6 允许生成器模式创建异步事件,这些事件仍然可以通过 try/catch 块捕获。
Koa(由 TJ Holowaychuck 编写,也是 Express.js 的原作者)明显做到了这一点。它使用 ES6
yield
语句来创建块,虽然看起来几乎同步,但以通常的节点异步方式处理:这个示例是从 此处。
Why first-parameter?
Because of the asynchronous nature of Node.js, the first-parameter-as-err pattern has become well established as a convention for userland Node.js error handling. This is because asynchronous:
So instead having the first argument of the callback is pretty much the only sensible way to pass errors asynchronously other than just throwing them.
To do so will result in an
unhandled exception
which, just in the way it sounds, implies that nothing was done to get the application out of its confused state.Exceptions, why do they exist
It is worth noting however, that virtually all part of Node.js are event-emitters and the throwing of an exception is a low-level event which can be handled like all events:
This can-but-shouldn't be taken to the extreme to catch all errors and make an application which will try very hard to never crash. This is a terrible idea in nearly every use-case, because it will leave the developer without any idea of what's going on in the application state and is analogous to wrapping main in try-catch.
Domains - grouping events logically
As part of dealing with this problem of exceptions making applications fall over, domains allow the developer to take, for example the Express.js application, and try and close off connections sensibly in the event of catastrophic failure.
ES6
It's probably mentioning that this will change again as ES6 allows the generator pattern to create asynchronous events which are still catchable with try/catch blocks.
Koa (written by TJ Holowaychuck, same original author of Express.js) noticeably does this. It uses the ES6
yield
statement to create blocks that, while appearing nearly syncronous, are handled in the usual node asynchronous fashion:This example was shamelessly stolen from here.