Error handling in Node.js + Express using promises

会有一股神秘感。 提交于 2020-01-24 05:28:04

问题


Using Node.js + Express (4) + Mongoose (using promises rather than callbacks), I can’t sort out how to tidy up my error handling.

What I've got (rather simplified) is:

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

Here, in the switch in the ‘promise rejected’ section, the Error is the error I threw myself for a potentially valid id which is not found, the CastError is Cast to ObjectId failed thrown by Mongoose for an invalid id, and the 500 error can for instance be triggered by mistyping throw Error() as throw Err() (causing a ReferenceError: Err is not defined).

But like this, every one of my routes has this great big clumsy switch to handle the different errors.

How can I centralise the error handling? Can the switch be tucked away into some middleware somehow?

(I did hope I could just re-throw using throw error; within the 'promise rejected' block, but I haven’t been able to make it work).


回答1:


I would create middleware to handle errors. Using next() for 404s. and next(err) for other errors.

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

404 handler

app.use(function(req, res) {
  return res.send('404');
});

Error handler

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

You can improve upon this more by sending a json response like:

return res.json({
  status: 'OK',
  result: someResult
});

or

return res.json({
  status: 'error',
  message: err
});


来源:https://stackoverflow.com/questions/26470535/error-handling-in-node-js-express-using-promises

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!