passport-local-mongoose: предупреждение о необработанном отказе: отклонение необработанного обещания

#express #async-await #passport.js #passport-local-mongoose

#экспресс #асинхронный-ожидание #passport.js #паспорт-местный-мангуст

Вопрос:

У меня есть рабочая реализация passport-local-mongoose, но я пытаюсь перейти к async / await и получаю сообщение об ошибке.

Вот мой контроллер:

 module.exports.register = async (req, res, next) => {

    const user = new User(),
        fillable = [
            'title',
            'firstName',
            'lastName',
            'practice',
            'addressLine1',
            'addressLine2',
            'city',
            'state',
            'postcode',
            'jobTitle',
            'country',
            'locale',
            'userRole',
            'termsAccepted',
            'consentOptIn',
            'username',
            'password',
            'legacyUserId',
            'authType'
        ]

    populateModel(user, fillable, req.body) // this is just a helper to set the schema from the request

    const result = await User.register(user, req.body.password).catch(next)

    return responseHelper.handleSuccess(res, {
        user: result
    })

}
 

У меня есть два обработчика ответов во вспомогательном модуле:

 module.exports.handleSuccess = (res, data) => {

  return res.json({
    message: 'Success.',
    data: data
  })

}

module.exports.handleUnexpectedError = (res, err) => {

  return res.status(err.status || 500).json({
    message: err.message || 'Internal Server Error.',
    error: err
  })

}
 

В моем приложении есть обработчик ошибок в качестве промежуточного программного обеспечения:

 app.use((err, req, res, next) => responseHelper.handleUnexpectedError(res, err))
 

И, наконец, мой маршрутизатор, который вызывает метод контроллера:

 router.post('/auth/register', authController.register)
 

Успешный ответ в порядке, и когда выдается ошибка и передается промежуточному программному обеспечению в этой строке, она возвращается, как и ожидалось:

 const result = await User.register(user, req.body.password).catch(next)
 

Однако, когда выдается эта ошибка, я получаю сообщение об ошибке в консоли:

 POST /v1/auth/register 500 166 - 9.253 ms
(node:21488) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:518:11)
    at ServerResponse.header (/Users/russback/Sites/api.alignpatientexperience.co.uk/node_modules/express/lib/response.js:771:10)
    at ServerResponse.send (/Users/russback/Sites/api.alignpatientexperience.co.uk/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/Users/russback/Sites/api.alignpatientexperience.co.uk/node_modules/express/lib/response.js:267:15)
    at Object.module.exports.handleSuccess (/Users/russback/Sites/api.alignpatientexperience.co.uk/helpers/responseHelper.js:95:14)
    at module.exports.register (/Users/russback/Sites/api.alignpatientexperience.co.uk/controllers/authController.js:64:27)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:21488) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
 

Кажется, вызывается мой обработчик успеха, а также мой обработчик ошибок, но я не уверен, где я ошибся.

Ответ №1:

Подумайте о том, чтобы обернуть запрос в блок try / catch и вызвать next обратный вызов в блоке catch.

 module.exports.register = async (req, res, next) => {

   const user = new User(),
       fillable = [
              ...
       ]

   populateModel(user, fillable, req.body) // this is just a helper to set the schema from the request

   try {
     const result = await User.register(user, req.body.password)

     return responseHelper.handleSuccess(res, {
       user: result
     })

   } catch(error) {
     next(error)
   }

}