【问题标题】:NodeJS: UnhandledPromiseRejectionWarning during changing passwordNodeJS:更改密码期间出现 UnhandledPromiseRejectionWarning
【发布时间】:2019-10-24 11:53:03
【问题描述】:

我正在处理 NodeJS 中的密码更改,在我的请求处理过程中出现以下错误:

(node:16220) UnhandledPromiseRejectionWarning: Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:491:11)
    at ServerResponse.setHeader (_http_outgoing.js:498:3)
    at ServerResponse.header (/home/pbaj/Documents/Projects/syberiaquotes-backend/node_modules/express/lib/response.js:771:10)
    at ServerResponse.send (/home/pbaj/Documents/Projects/syberiaquotes-backend/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/home/pbaj/Documents/Projects/syberiaquotes-backend/node_modules/express/lib/response.js:267:15)
    at user.(anonymous function).updateOne.then.catch.err (/home/pbaj/Documents/Projects/syberiaquotes-backend/api/controllers/user.js:284:52)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
(node:16220) 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(). (rejection id: 1)
(node:16220) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

在我的changePassword 路线中,我采用email,password,newPassword 值和:

  1. 检查电子邮件是否存在,如果存在...

  2. 比较给定密码和用户密码,如果它们相同...

  3. bcrypt.hash 函数获取 newPassword,从中生成哈希,并保存到 mongoDB

如果我提供正确的电子邮件和密码,以上所有点都已完成,但我知道UnhandledPromiseRejectionWarning

我看到这个问题的原因在 user[0].updateOne(user[0]) 函数内部,正好在 catch() 但我不知道发生了什么。

// CHANGE USER PASSWORD
exports.changePassword = (req, res, next) => {
    User.find({ email: req.body.email })
    .then(user => {
        if (user.length < 1) {
            return res.status(401).json({
                message: 'Auth failed'
            })
        }

        const { password, newPassword } = req.body
        console.log(password, newPassword)
        bcrypt.compare(req.body.password, user[0].password, (err, result) => {
            console.log(result)
            if (err) {
                return res.status(401).json({
                    message: 'Error! Something goes wrong'
                })
            }
            if (result) {
                bcrypt.hash(newPassword, 10, (err, hash) => {
                    console.log(hash)
                    if (err) {
                        return res.status(500).json({
                            error: err
                        })
                    } else {
                        user[0].password = hash
                        user[0]
                        .updateOne(user[0])
                        .then(result => {
                            return res.status(200).json({
                                message: 'Password changed!',
                                result: result,
                            })
                        })
                        .catch(err => {
                            res.status(500).json({ message: err.message })
                        })
                    }
                })
            }
            return res.status(401).json({
                message: 'Auth failed'
            })
        })
    })
    .catch(err => {
        res.status(500).json({ error: err })
    })
}

我需要从我的请求中得到[200]'Password changed!' 的答复,但由于UnhandledPromiseRejectionWarning,我得到了[401]'Auth failed'

【问题讨论】:

  • 你有任何中间件会响应 401 吗?

标签: javascript node.js mongodb error-handling change-password


【解决方案1】:

您发送了 2 次响应。试试这个代码

 if (result) {
            bcrypt.hash(newPassword, 10, (err, hash) => {
                console.log(hash)
                if (err) {
                    return res.status(500).json({
                        error: err
                    })
                } else {
                    user[0].password = hash
                    user[0]
                    .updateOne(user[0])
                    .then(result => {
                        return res.status(200).json({
                            message: 'Password changed!',
                            result: result,
                        })
                    })
                    .catch(err => {
                        res.status(500).json({ message: err.message })
                    })
                }
            })
} else {
          return res.status(401).json({
            message: 'Auth failed'
          })
}

【讨论】:

    【解决方案2】:

    我假设您使用的是 Mongoose(因为 User.find(...))。

    如果是这样,你就不能做user[0].updateOne(...),因为user[0]已经是一个User类型的对象。

    您要么使用User.findOneAndUpdate(...),要么在设置新密码后使用user[0].save(...)(这对我来说似乎更简单)。

    【讨论】:

    • updateOne()实际上是在文档上定义的:mongoosejs.com/docs/api/…
    • @c1moore,感谢您指出这一点。我没有意识到这一点,IMO 使用这种方法没有多大意义。
    猜你喜欢
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    相关资源
    最近更新 更多