首页 > 解决方案 > 执行登录路由时出现未处理的 Promise Rejection 警告错误

问题描述

谁能解释我的错误并给我解决方案?

代码是

router.post("/login", (req, res, next) => {
  if(!req.body.email || !req.body.password){
    return res.status(401).json({ success:false, message:'Email or Password Missing' });
  }

  let fetchedUser;

  const isEmailValid = emailPatternMatch(req.body.email);
  if(!isEmailValid){
    return res.status(401).json({ success:false, message:'Email not valid' });
  }

  User.findOne({email: req.body.email})
    .then(user => {
      if (!user){
        return res.status(401).json({ success: false, message:'Email Address is not Registered' });
      }

      fetchedUser = user;
      return bcrypt.compare(req.body.password, user.password);
    })
    .then(result=> {
      if(!result){
        return res.status(401).json({ success: false, message:'Incorrect Password' });
      }
      const token = jwt.sign({ email: fetchedUser.email, userId: fetchedUser._id }, scretKey, { expiresIn: "1h" } );
      return res.status(200).json({ success: true, token: token, userId: fetchedUser._id, expiresIn: 3600 });
    })
    .catch(err => {
      console.log(err);
      return res.status(401).json({ success:false, message: 'Authentication Failed' });
    });
});

错误是

(节点:4084)UnhandledPromiseRejectionWarning:错误 [ERR_HTTP_HEADERS_SENT]:在 ServerResponse.header (C:\Users\umesh\Desktop\Locationist \node_modules\express\lib\response.js:771:10) 在 ServerResponse.send (C:\Users\umesh\Desktop\Locationist\node_modules\express\lib\response.js:170:12) 在 ServerResponse.json ( C:\Users\umesh\Desktop\Locationist\node_modules\express\lib\response.js:267:15) 在 C:\Users\umesh\Desktop\Locationist\backend\routes\user.js:82:30 在 processTicksAndRejections (internal/process/task_queues.js:97:5) (node:4084) UnhandledPromiseRejectionWarning:未处理的承诺拒绝。此错误源于在没有 catch 块的情况下抛出异步函数内部,或拒绝未使用 .catch() 处理的承诺。要在未处理的 Promise 拒绝时终止节点进程,请使用 CLI 标志--unhandled-rejections=strict (见https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode)。(拒绝 id:1)(节点:4084)[DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。将来,未处理的 Promise 拒绝将使用非零退出代码终止 Node.js 进程。

标签: javascriptnode.js

解决方案


我注意到,如果找不到用户,您首先then会打电话。res.status在你的 nextthen中,你可能会res.status再次调用,这将导致 promise 被拒绝,因为它已经被调用了。在你的catch你再次调用res.status,从而拒绝了那个没有任何问题的承诺,导致一个未处理的承诺。

要解决此问题,您需要避免res.status多次调用。你可以例如在你的抛出一个异常then并让你catch处理它:

...
User.findOne({email: req.body.email})
    .then(user => {
      if (!user){
        throw { success: false, message:'Email Address is not Registered' };
      }

      fetchedUser = user;
      return bcrypt.compare(req.body.password, user.password);
    })
    .then(result=> {
      if(!result){
        throw { success: false, message:'Incorrect Password' };
      }
      const token = jwt.sign({ email: fetchedUser.email, userId: fetchedUser._id }, scretKey, { expiresIn: "1h" } );
      return res.status(200).json({ success: true, token: token, userId: fetchedUser._id, expiresIn: 3600 });
    })
    .catch(err => {
      console.log(err);
      return res.status(401).json(err);
    });

推荐阅读