节点,Express,域,未捕获的exception – 仍然丢失

我一直在读Node几个小时的exception处理。 我理解使用uncaughtException的缺点,我知道closures这个过程对于防止任何可能发生的“未知状态”是有好处的。 我明白,使用域是要走的路,我明白如何正确地实现域,特别是显式绑定 …

…但我仍然没有得到任何结果只是基本的error handling。

我希望能够捕获任何未捕获的exception,以便logging。 我不介意杀死这个进程或其他被认为是“不可取的”的东西。 我只想要一个日志。

我不觉得我应该把所有的东西都放在try / catch中,或者用一些库来emit错误…如果我错了,请纠正我,我会改变我的方式。

我正在使用Node和Express,我有以下简单的代码:

 var express = require('express'); var domain = require('domain'); var serverDomain = domain.create(); serverDomain.on('error', function(err) { console.log("SERVER DOMAIN ERROR: " + err.message); }); serverDomain.run(function() { var app = express(); app.get('/testing', function() { app.nonExistent.call(); // this throws an error }); var server = app.listen(8000, function() { console.log('Listening on port %d', server.address().port); }); }); 

错误显示在控制台中,但控制台永远不会收到“SERVER DOMAIN ERROR …”消息。 我也尝试在自己的域中包装请求/响应,无济于事。 更令人失望的是,使用以下内容也不起作用:

 process.on('uncaughtException', function(err) { console.log('uncaughtException caught the error'); }); 

难道我做错了什么? 我从哪里出发? 我怎样才能捕捉到上述错误?

你可以使用连接域 。

问题是Connect的路由过程中发生了exception,在执行过程中有一个try / catch块,以及一个默认的error handling程序,在非生产模式下运行时会打印出堆栈跟踪详细信息。 由于exception是在Express内部处理的,因此它永远不会到达您的外层以供域处理。

这是一个为什么使用连接域包而不是域的例子。

http://masashi-k.blogspot.com/2012/12/express3-global-error-handling-domain.html

 var express = require('express'); var connectDomain = require('connect-domain'); var app = express(); app.use(connectDomain()); app.get('/testing', function() { app.nonExistent.call(); // this throws an error }); app.use(function(err, req, res, next) { res.end(err.message); // this catches the error!! }); var server = app.listen(8000, function() { console.log('Listening on port %d', server.address().port); }); 

发生这种情况是因为Express本身处理可能出现的错误,并以这种方式简化了您的工作。 请参阅快速指南了解error handling 。 您应该使用下面的结构来处理可能出现的错误:

 app.use(function(err, req, res, next){ console.error(err.stack); res.send(500, 'Something broke!'); });