error handlingNode.js + Express.js应用程序的原则?

与其他框架相比,Node.js + Express.js应用程序的错误报告/处理似乎有所不同。 我的理解是正确的,它的工作原理如下?

A)通过接收它们作为你的callback函数的参数来检测错误。 例如:

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()configuration自己的error handling程序来处理错误,或者使用通用的Connecterror handling程序。 例:

 app.error(function(err, req, res, next) { console.error(err); res.send('Fail Whale, yo.'); }); 

这四个原则是Node.js + Express.js应用程序中所有error handling/报告的基础吗?

Node.js中的error handling通常是格式A)。 大多数callback函数将返回一个错误对象作为第一个参数或null

Express.js使用中间件,中间件语法使用B)和E)(在下面提到)。

C)如果你问我,是不好的做法。

 app.get('/home', function(req, res) { // An error occurs throw err; }); 

你可以很容易地重写上面的

 app.get('/home', function(req, res, next) { // An error occurs next(err); }); 

中间件语法在get请求中有效。

至于D)

(07:26:37 PM)tjholowaychuk:app.error在3.x中被删除

TJ刚刚确认app.error已经被弃用,而转而使用E

E)

 app.use(function(err, req, res, next) { // Only handle `next(err)` calls }); 

任何长度为4(4个参数)的中间件都被视为错误中间件。 当next(err)调用next(err)连接时,调用基于错误的中间件。

Joyent的人们已经发表了一篇非常有见地的最佳实践文档 。 任何Node.js开发人员必读的文章。

为什么是第一个参数?

由于Node.js的asynchronous特性,作为用户级Node.jserror handling的惯例,第一个参数作为err模式已经被很好地build立。 这是因为asynchronous:

 try { setTimeout(function() { throw 'something broke' //Some random error }, 5) } catch(e) { //Will never get caught } 

因此,除了抛出它们之外,拥有callback的第一个参数几乎是唯一可以asynchronous传递错误的合理方法。

这样做会导致一个unhandled exception ,就像听起来一样,意味着没有任何东西可以让应用程序摆脱困境。

例外,他们为什么存在

但值得注意的是,事实上,Node.js的所有部分都是事件发射器,抛出exception是一个低级事件,可以像所有事件一样处理:

 //This won't immediately crash if connection fails var socket = require("net").createConnection(5000); socket.on("error", function(err) { console.error("calm down...", err) }); 

为了避免所有的错误 ,我们不能采取极端的措施,而要做出一个非常努力的应用程序,永远不会崩溃。 在几乎所有的用例中,这都是一个糟糕的主意,因为这会让开发人员不知道应用程序状态是怎么回事,类似于将主要包装放在try-catch中。

域 – 从逻辑上将事件分组

作为处理应用程序崩溃的exception问题的一部分, 域允许开发人员采取(例如)Express.js应用程序,并在发生灾难性故障时尝试closures连接。

ES6

这可能是因为ES6允许生成器模式创build仍然可以被try / catch块捕获的asynchronous事件,这可能会再次改变。

Koa(由TJ Holowaychuck撰写,Express.js的原创作者)显然是这样做的。 它使用ES6 yield语句来创build块,虽然几乎同步出现,但是以通常的节点asynchronous方式处理:

 app.use(function *(next) { try { yield next; } catch (err) { this.status = err.status || 500; this.body = err.message; this.app.emit('error', err, this); } }); app.use(function *(next) { throw new Error('some error'); }) 

这个例子从这里被无耻地偷走了 。