UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性“ roleId”

时间:2020-07-21 14:57:19

标签: node.js mongodb promise

我有一项要求,要求我验证用户是否选择了正确的经理。它们之间的关联是每个人所属的组ID。用户可以与一个组ID关联,而经理可以与多个组ID关联。当允许用户选择他的管理员时,我需要验证用户的组ID是否在管理员的组ID列表中。这是我在下面实现的代码,但我得到 UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性'roleId'

我的路线文件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:无法读取未定义的属性'roleId'

的地方。

我已经在第一次调用find查询中放置了一个wait,它按预期的方式工作,等待调用完成,但是下一次wait似乎没有任何效果。执行并没有等待调用结束。

你能帮我在这里想念的吗?

谢谢, 赫曼特。

1 个答案:

答案 0 :(得分:0)

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

此外,您不应该将async 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;
    }
};