首页 > 解决方案 > 我在承诺链中有 catch() 但仍然得到未处理的承诺拒绝

问题描述

我发现很多线程都有同样的问题,但几乎所有线程都没有 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 都不应该有任何问题,我不明白为什么我的代码仍然显示未处理的承诺拒绝

标签: javascriptnode.jsexpresspromise

解决方案


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

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

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

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

res.send({errorMessage: errMessage})

推荐阅读