我开始使用Express JS并遇到了一个问题。我似乎无法弄清楚处理错误的正确方法。
例如,我有一个Web服务API,它提供一个名为“event”的对象。当用户提交未找到的事件ID时,我想返回一个简单的“无法查找事件”字符串。以下是我目前正在构建代码的方式:
app.get('/event/:id', function(req, res, next) {
if (req.params.id != 1) {
next(new Error('cannot find event ' + req.params.id));
}
req.send('event found!');
});
当我提交 id 而不是1时,Node会崩溃并输出以下内容:
http.js:527
throw new Error("Can't set headers after they are sent.");
^
Error: Can't set headers after they are sent.
at ServerResponse.<anonymous> (http.js:527:11)
at ServerResponse.setHeader (/usr/local/kayak/node_modules/express/node_modules/connect/lib/patch.js:62:20)
at /usr/local/kayak/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js:72:19
at [object Object].<anonymous> (fs.js:107:5)
at [object Object].emit (events.js:61:17)
at afterRead (fs.js:878:12)
at wrapper (fs.js:245:17)
通过使用node.js debugger ,我可以在调用next()
后继续执行代码块,这意味着req.send('event found!')
尝试运行。我不希望这种情况发生。
我发现的唯一解决方法是简单地抛出new Error()
而不是“下一步”它,但这会导致生成默认的Express HTML错误页面。我想要更多的控制权。
我花了很多时间阅读Express文档的error handling section,但我无法理解它。
答案 0 :(得分:35)
您需要查看Express Error Handling。从那里:
app.param('userId', function(req, res, next, id) {
User.get(id, function(err, user) {
if (err) return next(err);
if (!user) return next(new Error('failed to find user'));
req.user = user;
next();
});
});
您缺少的甜点是 return
next(...)
答案 1 :(得分:19)
那是因为你做错了:你已经抛出一个错误(将由Express处理并为用户返回500 - 错误页面或类似的东西)但你也试图发送自己的回复客户端:res.send('event found!');
您应该在这里查看有关错误处理的Express指南:http://expressjs.com/guide/error-handling.html
我在你的例子中会做的是:
function NotFound(msg){
this.name = 'NotFound';
Error.call(this, msg);
Error.captureStackTrace(this, arguments.callee);
}
app.get('/event/:id', function(req, res, next){
if (req.params.id != 1) {
throw new NotFound('Cannot find event ' + req.params.id);
} else {
res.send('event found!');
}
});
app.error(function(err, req, res, next){
if (err instanceof NotFound) {
res.render('404.ejs');
} else {
next(err);
}
});
答案 2 :(得分:10)
您的代码中存在一些问题:
在回复客户端时,您需要使用 响应对象(res
而不是req
)。
向next
发送错误时,您应该 返回 ,因此该功能的其余部分不会运行。
修复这些错误后,这是您的代码:
app.get('/event/:id', function(req, res, next) {
if (req.params.id != 1) {
return next(new Error('cannot find event ' + req.params.id));
}
res.send('event found!'); // use res.send (NOT req.send)
});