我一直在阅读Node中的异常处理数小时。我理解使用uncaughtException
的缺点,我知道关闭这个过程有利于防止任何未知状态"在哪里"任何事情都可能发生"。我了解使用domains是可行的方法,我了解如何正确实施域名,特别是Explicit Binding ...
...但我仍然没有得到任何基本错误处理的结果。
我希望能够捕获任何未捕获的异常以进行日志记录。我不介意杀死这个过程或任何其他被认为是不受欢迎的事情"。我只想要一个日志。
我觉得我不应该在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');
});
我做错了吗?我从哪里开始?我怎样才能发现上述错误?
答案 0 :(得分:5)
这是因为Express会自行处理可能出现的错误,并以这种方式简化您的工作。见Express Guide for error handling。您应该使用下面的结构来处理可能出现的错误:
app.use(function(err, req, res, next){
console.error(err.stack);
res.send(500, 'Something broke!');
});
答案 1 :(得分:5)
您可以使用connect-domain。
问题是在Connect的路由期间发生了异常,它在执行时都有一个try / catch块,以及一个默认的错误处理程序,它在非生产中运行时打印出堆栈跟踪详细信息模式。由于异常是在Express内部处理的,因此它永远不会到达外层以供域处理。
以下是使用connect-domain包而不是域的示例。
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);
});