Как NodeJS и ExpressJS могут выдавать ошибку?

#node.js #mongodb #express

#node.js #mongodb #выразить

Вопрос:

Веб-приложение использует express для сервера, Nodejs в качестве языка, MongoDB в качестве базы данных и mongoose в качестве оболочки. Express запускает сервер на порту 3000, и я пытаюсь реализовать базовый CRUD для коллекции. Я использую Newrelic для генерации графиков, и я вижу, что при ошибке экспресс-выдачи время отклика сервера увеличивается, например :

 User.findOne({ $or: [{ email: { $regex: new RegExp(email, 'i') } }, { userLogin: { $regex: new RegExp(userLogin, 'i') } }] }, 'id').exec()
    .then(results => {
        if (results) { throw new APIError('email_taken') } 
        else { return results }
  }).then(result => {
      res.status(201).success(result)
    }, error => {
      res.error(error)
    })
 

Я действительно не понимаю, почему серверное время увеличивается, когда ExpressJS выдает подобную ошибку.
Я хочу знать, есть ли в моем методе ошибка или есть другой метод лучше.
И спасибо.

Ответ №1:

Если вы просмотрите документацию ExpressJS по обработке ошибок, в ней указано, что

Ошибки, возникающие в синхронном коде внутри обработчиков маршрутов и промежуточного программного обеспечения, не требуют дополнительной работы. Если синхронный код выдает ошибку, то Express перехватит и обработает ее.

Но

Для ошибок, возвращаемых из асинхронных функций, вызываемых обработчиками маршрутов и промежуточным программным обеспечением, вы должны передать их функции next(), где Express перехватит и обработает их.

Поскольку ваша работа с базой данных асинхронна по своей природе, вы всегда должны передавать ошибку в next(), чтобы обработать ее должным образом

Пример

 app.get("/", function (req, res, next) {
  fs.readFile("/file-does-not-exist", function (err, data) {
    if (err) {
      next(err); // Pass errors to Express.
    }
    else {
      res.send(data);
    }
  });
});
 

Комментарии:

1. Я действительно использую это app.use(function (req, res, next) { res.setHeader('Content-Type', 'application/json') res.success = function (obj) { res.send(APIResponse(obj)) } res.error = function (param1, param2) { let error if (param1.constructor === APIError) { error = param1 } else if (typeof (param1) === 'string') { error = new APIError(param1, param2) } else { error = new APIError('unknown') } res.status(error.status).send({ 'success': false, 'error': { 'code': error.code, 'message': error.message } }) } next() })

2. Что значит, что вы это используете? Я просмотрел код, который вы прокомментировали, но я пытаюсь сказать, что из-за асинхронного характера задачи ошибка передается в next()

3. Можете ли вы исправить этот код User.findOne({ $or: [{ email: { $regex: new RegExp(email, 'i') } }, { userLogin: { $regex: new RegExp(userLogin, 'i') } }] }, 'id').exec() .then(results => { if (results) { throw new APIError('email_taken') } else { return results } }).then(result => { res.status(201).success(result) }, error => { res.error(error) })

4. module.exports.login = function (req, res, next) { User.findOne({ $или: [{ ‘auth. local.email’: emailOrUserLogin }, { ‘auth. local.UserLogin’: emailOrUserLogin }] }).exec() .then(результаты => { if (результаты) { возвращать результаты } else { возвращать next(новая ошибка ApiError(‘login_failed’)) } }) }