使用promises在Node.js + Express中处理错误

Chr*_*isV 4 error-handling mongoose node.js promise express

使用Node.js + Express(4)+ Mongoose(使用promises而不是回调),我无法理清如何整理我的错误处理.

我得到的(相当简化)是:

app.get('/xxx/:id', function(request, response) {
    Xxx.findById(request.params.id).exec()
        .then(function(xxx) {
            if (xxx == null) throw Error('Xxx '+request.params.id+' not found');
            response.send('Found xxx '+request.params.id);
        })
        .then(null, function(error) { // promise rejected
            switch (error.name) {
                case 'Error':
                    response.status(404).send(error.message); // xxx not found
                    break;
                case 'CastError':
                    response.status(404).send('Invalid id '+request.params.id);
                    break;
                default:
                    response.status(500).send(error.message);
                    break;
            }
        });
});
Run Code Online (Sandbox Code Playgroud)

在这里,在'promise rejected'部分的开关中,Error是我为自己找不到的潜在有效id而犯的错误,CastError是Mongoose为无效的id抛出的Cast to ObjectId失败,500错误可以为例如,通过键入错误被触发throw Error()作为throw Err()(导致的ReferenceError:未定义ERR).

但是像这样,我的每条路线都有这个非常笨拙的开关来处理不同的错误.

如何集中处理错误?交换机可以以某种方式隐藏在一些中间件中吗?

(我确实希望我可以throw error;在'承诺拒绝'块中重新使用,但我无法使其工作).

Jor*_*ias 7

我会创建中间件来处理错误.使用next()了404.以及next(err)其他错误.

app.get('/xxx/:id', function(req, res, next) {
  Xxx.findById(req.params.id).exec()
    .then(function(xxx) {
      if (xxx == null) return next(); // Not found
      return res.send('Found xxx '+request.params.id);
    })
    .then(null, function(err) {
      return next(err);
    });
});
Run Code Online (Sandbox Code Playgroud)

404处理程序

app.use(function(req, res) {
  return res.send('404');
});
Run Code Online (Sandbox Code Playgroud)

错误处理程序

app.use(function(err, req, res) {
  switch (err.name) {
    case 'CastError':
      res.status(400); // Bad Request
      return res.send('400');
    default:
      res.status(500); // Internal server error
      return res.send('500');
  }
});
Run Code Online (Sandbox Code Playgroud)

您可以通过发送json响应来改进这一点:

return res.json({
  status: 'OK',
  result: someResult
});
Run Code Online (Sandbox Code Playgroud)

要么

return res.json({
  status: 'error',
  message: err
});
Run Code Online (Sandbox Code Playgroud)

  • 当我按照你的建议添加`return next(err);`时,它会进入那个语句,然后只是坐在那里'等待本地主机......'.如果你确信这种方法应该有效,也许我的代码中还有其他错误,但我不能为我的生活看到什么! (2认同)