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