首页 > 解决方案 > UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性“roleId”

问题描述

我有一个要求,要求我验证用户是否选择了正确的经理。它们之间的关联是各自所属的组 id。一个用户可以与一个组 id 相关联,一个管理员可以与多个组 id 相关联。当允许用户选择他的经理时,我需要验证用户的组 ID 是否存在于经理的组 ID 列表中。这是我在下面实现的代码,但我得到UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'roleId' of undefined

我的路由文件 account.ts 有以下代码块

let promise = accountController.update(user);
        promise.then(function(data) {
            if (data.IsSuccessful == true)
            {
                result.IsSuccessful = true;
                result.SuccessMessage = process.env.USER_UPDATED || "User changed";
                return res.status(200).json(result);
            } 
            else 
            {
                result.IsSuccessful = false;
                result.ReasonForFailure = data.ReasonForFailure;
                res.status(200).json(result);
            }
        }).catch(function(err){
            result.IsSuccessful = false;
            result.ReasonForFailure = err.message;
            res.status(200).json(result);
        });

我的控制器文件 account.ts 具有以下更新方法的代码块

update = (account: Account) : Promise<Result<Account>> => {
        var thisObj = this;
        return new Promise<Result<Account>>(function (resolve, reject){
            let result = new Result<Account>();
            result.Data = account;
            MongoClient.connect(config.database.uri, { useUnifiedTopology: true } , async function(err: any, db: any) {
                if (err) {
                   // throw err;
                   result.IsSuccessful = false;
                   result.ReasonForFailure = err.message;
                   reject(result);
               } 
                   
                var dbo = db.db(config.database.name);
                   
                var newvalues = { $set: 
                    {
                        name: account.name,
                        title: account.title,
                        organization: account.organization,
                        reportingTo: account.reportingTo,
                        workNumber: account.workNumber,
                        mobileNumber: account.mobileNumber,
                        allowNotification: account.allowNotification,
                        allowEmail: account.allowEmail,
                        groups: account.groups,
                        updatedDate: account.updatedDate,
                        isProfileSetupComplete: true,
                        photo:account.photo
                    }
                };
                
                let existingUser: any;
                var query = {email:account.email};
                
                var resultArray = await dbo.collection("users").find(query).toArray();

                if (resultArray.length > 0) {
                    existingUser = resultArray[0];                        
                } else {
                    db.close();
                    result.ReasonForFailure = process.env.INVALID_USER_ID || "Invalid User Id";
                    result.IsSuccessful = false;
                    reject(result);
                }

                console.log(existingUser);
                if (existingUser.roleId == "1") { //roleId="1" means user
                    //validate manager id. reportingTo id must be a manager

                    var queryReporting = { _id: account.reportingTo };
                    let managerUser: any;
                    var resultManagerArray = await dbo.collection("users").find(queryReporting).toArray();
                    if (resultManagerArray.length > 0) {
                        console.log("managerUser in");//<--This is not printing in the console log
                        managerUser = resultManagerArray[0];                        
                    } else {
                        db.close();
                        result.ReasonForFailure = "Invalid reporting id.";// process.env.INVALID_USER_ID || "Invalid User Id";
                        result.IsSuccessful = false;
                        resolve(result);                        
                    }                    

                    //validate manager user
                    console.log("managerUser out");
                    console.log(managerUser);
                    if (managerUser.roleId !== "2"){//<--UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'roleId' of undefined
                        result.IsSuccessful = false;
                        result.ReasonForFailure = "Reporting to must be a Manager";
                        reject(result);
                    } 

                    //manager and user must be associated with same group
                    if (!managerUser.groups.includes(account.groups)) {
                        result.IsSuccessful = false;
                        result.ReasonForFailure = "Incorrect Manager selection. Employee must be associated with a group the manager is associated with."
                        reject(result);
                    }
                }

                dbo.collection("users").updateOne(query, newvalues, function(err: any, resultSet: any) {
                    if (err) {
                        //throw err;
                        db.close();
                        result.IsSuccessful = false;
                        result.ReasonForFailure = err.message;
                        reject(result);
                    } else {
                        result.SuccessMessage = oldImage;
                        result.IsSuccessful = true;
                        db.close();
                        resolve(result);
                    }
                });
             });
        });
    }

上面代码中的 managerUser.roleId !== "2" 是我得到UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'roleId' of undefined

我在第一次调用 find 查询时放了 await ,它按预期工作,等待调用完成,但下一次 await 似乎没有效果。执行没有等待调用完成。

你能帮助我在这里缺少什么吗?

谢谢,赫曼特。

标签: node.jsmongodbpromise

解决方案


在所有/调用之后,您可能缺少return语句。与and不同,它们是普通的函数调用,不会终止函数的执行。resolve(result);reject(result);returnthrow

此外,您不应将 anasync function作为回调传递给不处理返回的承诺的函数。你应该只承诺connect单独的调用,等待它的结果,然后await在回调之后或then回调中继续你的函数的其余部分,以确保正确处理错误。

update = async (account: Account) : Promise<Result<Account>> => {
    let result = new Result<Account>();
    result.Data = account;
    try {
        const db = await MongoClient.connect(config.database.uri, { useUnifiedTopology: true });
        try {
            const dbo = db.db(config.database.name);

            const newvalues = {
                $set: {
                    name: account.name,
                    title: account.title,
                    organization: account.organization,
                    reportingTo: account.reportingTo,
                    workNumber: account.workNumber,
                    mobileNumber: account.mobileNumber,
                    allowNotification: account.allowNotification,
                    allowEmail: account.allowEmail,
                    groups: account.groups,
                    updatedDate: account.updatedDate,
                    isProfileSetupComplete: true,
                    photo:account.photo
                }
            };
            var resultArray = await dbo.collection("users").find({email: account.email}).toArray();

            if (resultArray.length == 0) {
                result.ReasonForFailure = process.env.INVALID_USER_ID || "Invalid User Id";
                result.IsSuccessful = false;
                return result;
            }
            const existingUser = resultArray[0];
            console.log(existingUser);

            if (existingUser.roleId == "1") {
                var resultManagerArray = await dbo.collection("users").find({ _id: account.reportingTo }).toArray();
                if (resultManagerArray.length == 0) {
                    result.ReasonForFailure = "Invalid reporting id.";// process.env.INVALID_USER_ID || "Invalid User Id";
                    result.IsSuccessful = false;
                    return result;
                }
                console.log("managerUser in");
                const managerUser = resultManagerArray[0];
                console.log("managerUser out");
                console.log(managerUser);

                if (managerUser.roleId !== "2") {
                    result.IsSuccessful = false;
                    result.ReasonForFailure = "Reporting to must be a Manager";
                    return result;
                }

                //manager and user must be associated with same group
                if (!managerUser.groups.includes(account.groups)) {
                    result.IsSuccessful = false;
                    result.ReasonForFailure = "Incorrect Manager selection. Employee must be associated with a group the manager is associated with."
                    return result;
                }
            }

            const resultSet = await dbo.collection("users").updateOne(query, newvalues);
            result.SuccessMessage = oldImage;
            result.IsSuccessful = true;
            return result;
        } finally {
            db.close()
        }
    } catch(err) {
        result.IsSuccessful = false;
        result.ReasonForFailure = err.message;
        return result;
    }
};

推荐阅读