【问题标题】:I have catch() in promise chain but still gets unhandled promise rejection我在承诺链中有 catch() 但仍然得到未处理的承诺拒绝
【发布时间】:2021-06-29 15:01:59
【问题描述】:

我发现很多线程都有同样的问题,但几乎所有线程都没有 catch() 或使用了错误的承诺链。 当用户输入错误的密码或标识并且登录失败时,我正在测试这种情况。 在我的代码中,我认为我在 catch() 中正确使用了 Promise 链,但我仍然收到未处理的 Promise 拒绝错误。 该网站应在网站上显示类似“密码错误”的错误消息。

代码用 node.js 和 express.js 编写

这是我的代码: app.js

app.post('/:login',(req,res)=>{
 const userId = req.body.userId;
 const userPw = req.body.userPW;
 try{
  if(userId.length<5&&userPw.length<5){
    throw "Id and password must be minimum 5 characters";
  }else if(userId.length>=5&&userPw.length<5){
    throw "Password must be minimum 5 characters";
  }else if(userId.length<5&&userPw.length>=5){
    throw "Id must be minimum 5 characters";
  }else{
    dbFile.checkIfUserExists(userId,userPw,res)
    .then((response)=>{
      console.log(response[0].userId);
      return response[0].userId;
    }).catch((errMessage)=>{
      console.log(errMessage);
      throw errMessage;
    })
  }
}
 catch(e){
  console.log(e);
  res.send({
    errorMessage:e
  })
 }
});

userListDB.js

const mysql = require('mysql');

function createMySQLConnection(){
    const connection = mysql.createConnection({
        host:'localhost',
        user:'root',
        password:'',
        database:'chatdatabase'
    });
    return connection;
}
function connectToDB(connection){
    try{
        connection.connect(function(err){
            if(err){
                throw "Sorry, something happened. Please try later";
            }
        })
    }catch(error){
        return error;
    }
}
module.exports={
    checkIfUserExists:function(id,pw,res){
        const connection = createMySQLConnection();
        if(connectToDB(connection)===undefined||connectToDB(connection)===null){
            const sql = "SELECT * FROM userlist WHERE userId=? AND password=?";
            return new Promise((resolve,reject)=>{
                connection.query(sql,[id,pw],(error,result)=>{
                    try{
                        if(error){
                            throw error;
                        }
                        else if(result.length===0){
                            throw "It seems like your id and password don't match. please try again with different id and password";
                        }
                        else{
                            resolve(result);
                        }
                    }catch(e){
                        reject(e);
                    }
                })
            })
        }
    }
}

我知道我没有进行密码加密,但我会在此问题解决后进行。 正如您在代码中看到的,当用户发送 POST 登录请求时,app.js 中的 app.post 将验证数据,如果没有问题,它将从 dbUserList.js 调用 dbFile.checkIfUserExists。 dbUserList 返回一个承诺,所以我在 app.post 中使用 .then().catch() 创建了一个承诺链。

但我还是得到了

It seems like your id and password don't match. please try again with different id and password
(node:7896) UnhandledPromiseRejectionWarning: It seems like your id and password don't match. please try again with different id and password
(Use `node --trace-warnings ...` to show where the warning was created)
(node:7896) 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)
(node:7896) [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.

我发现 then().catch() 中的 console.log 有效,所以两个 try catch 都应该没有问题,我不明白为什么我的代码仍然显示未处理的承诺拒绝

【问题讨论】:

  • 好吧,如果你在最终的.catch 回调中有一个throw,那么你确实有一个未处理的承诺拒绝。
  • @trincot 哦,真的吗?你救了我的命。谢谢,但是如果 throw 调用拒绝,如何将错误数据发送到外部捕获? catch 在 try catch 里面,不知何故我必须将消息扔给 catch()...
  • 不要尝试进入外部try catch 块,因为您无法异步使用该代码。只需在该位置发送错误即可。看我的回答。

标签: javascript node.js express promise


【解决方案1】:

确实,您有一个未处理的承诺拒绝:

.catch((errMessage)=>{
  console.log(errMessage);
  throw errMessage;
})

.catch 位于 Promise 链的末尾,因此返回一个 Promise。现在,如果您进入catch 回调和throw,那么这将使该promise 处于被拒绝状态,并且没有更多处理该拒绝的处理程序。

你应该在那个地方直接发送,而不是扔:

res.send({errorMessage: errMessage})

【讨论】:

  • 谢谢,我自己尝试了几天解决这个问题,但还是不行,你救了我的命!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
  • 2023-03-17
  • 2018-04-01
  • 2021-09-19
相关资源
最近更新 更多