如何正确处理Express中的错误?

我开始与Express JS合作,并遇到了一个问题。 我似乎无法弄清楚处理错误的正确方法。

例如,我有一个Web服务API,提供一个名为“事件”的对象。 我想返回一个简单的string“无法find事件”,当用户提交一个事件ID没有find。 这是我目前正在构build我的代码:

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!'); }); 

当我提交一个不是1的id时 ,节点崩溃,输出如下:

 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 debugging器可以知道,代码块的执行在next()被调用后继续执行,这意味着req.send('event found!')试图运行。 我不想要这样的事情发生。

我find的唯一的解决方法是简单地抛出一个new Error()而不是“下一个”它,但这会导致生成一个默认的Express HTML错误页面。 我想多一点控制。

我已经花时间阅读了Express文档的error handling部分 ,但我无法理解它。

你会想看看快速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(); }); }); 

你缺less的甜点是return next(...)

这是因为你做错了:你已经抛出一个错误(这将被快递处理,并返回一个500错误页面的用户或类似的东西),但你也试图发送你自己的响应到客户端: res.send('event found!');

您应该仔细查看有关error handling的快速指南: 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); } }); 

你的代码中有几个问题:

  • 在响应客户端时,您需要使用响应对象res而不是req )。

  • 当发送一个错误到next ,你应该返回 ,所以其余的function不运行。

修复这些错误之后,您的代码如下:

 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) });