如何添加 catch 语句来修复未处理的承诺拒绝警告

How to add a catch statement to fix Unhandled promise rejection warning

我正在尝试向我的站点添加用户身份验证。我页面上的注册路由运行良好,但当我尝试向登录路由发送请求时收到未处理的承诺拒绝警告。

我试过添加 .catch(err => console.log(err));.catch(console.log("Something's gone wrong."));.findOne().then().compare().then() 的末尾,但这没有帮助。

router.post("/login", (req, res) => {
  const email = req.body.email;
  const password = req.body.passowrd;

  User.findOne({ email }).then(user => {
    if (!user) {
      return res.status(404).json({ email: "User not found" });
    }

    bcrypt.compare(password, user.passowrd).then(isMatch => {
      if (isMatch) {
        res.json({ msg: "Success" });
      } else {
        return res.status(400).json({ password: "Password incorrect" });
      }
    });
  });
});

该代码应该只是发回密码匹配的消息,以便我稍后可以生成令牌。我收到此错误:

(node:18152) UnhandledPromiseRejectionWarning: Error: Illegal arguments: undefined, undefined
    at _async (/home/jok/code/node_modules/bcryptjs/dist/bcrypt.js:286:46)
    at /home/jok/code/node_modules/bcryptjs/dist/bcrypt.js:307:17
    at new Promise (<anonymous>)
    at Object.bcrypt.compare (/home/jok/code/node_modules/bcryptjs/dist/bcrypt.js:306:20)
    at User.findOne.then.user (/home/jok/code/routes/api/users.js:64:12)
    at processTicksAndRejections (internal/process/next_tick.js:81:5)
(node:18152) 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:18152) [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.

发生 UnhandledPromiseRejectionWarning 是因为您没有处理 Promise 拒绝,这意味着您缺少 .catch 处理程序。

bcrypt.compare(password, user.passowrd).then(isMatch => {
  if (isMatch) {
    res.json({ msg: "Success" });
  } else {
    return res.status(400).json({ password: "Password incorrect" });
  }
})
.catch(err => {
    res.status(500).send('Internal server error');
});

在这种特殊情况下,passworduser.passowrd 似乎是 undefined。后者可能是因为打字错误:passowrd => password.

因此建议检查发送到路由的参数是否有效。

router.post("/login", (req, res) => {
  const email = req.body.email;
  const password = req.body.passowrd;

  if(!email || !password)
    return res.status(400).send('email & password are required');

  /* ... */
});

由于您在 .findOne Promise 上也缺少 .catch 处理程序,因此最好将 Promise 链接起来,而不是像您正在做的那样嵌套它们。所以这是完整的代码:

router.post("/login", (req, res) => {
    const email = req.body.email;
    const password = req.body.passowrd;

    if (!email || !password)
        return res.status(400).send('email & password are required');

    User.findOne({ email })
        .then(user => {
            if (!user) {
                return res.status(404)
                    .json({ message: "User not found" });
            }

            return bcrypt.compare(password, user.passowrd);
        })
        .then(isMatch => {

            if (typeof isMatch !== 'boolean')
                return; // result from `res.status(404)...`

            if (isMatch)
                return res.json({ message: "Success" });

            return res.status(400)
                .json({ message: "Password incorrect" });

        })
        .catch(err => {
            res.status(500).json({ message: 'Internal server error' });
        });

 });

I've tried adding .catch(err => console.log(err)); and .catch(console.log("Something's gone wrong.")); to the end of both .findOne().then() and .compare().then(), but that didn't help.

您没有正确附加处理程序,或者警告是在其他代码中触发的。但是由于提供的代码没有你提到的 .catch ,我无法确认。无论如何,上面的代码片段不会触发 UnhandledPromiseRejectionWarning

bcrypt.compare(myPlaintextPassword, hash, function(err, res) {
    if (err) {
      console.log(err);
    }
    
    // Use your response
});

在简单的逻辑中没有必要使用 promises。