简体   繁体   中英

Node JS application get stuck at resolve()

I am facing an issue in my node js application while listing the aws cognito users.

This issue is coming only while i have more than 60 cognito users.

Reference of API

Below is my code snippet.

function isAllowedToDeleteOrRevokeUsers(cognitoidentityserviceprovider, params, listUsers, adminUserList) {
return new Promise(function(resolve, reject) {
  cognitoidentityserviceprovider.listUsers(params, function(err, data) {
       if (err) {
           logger.log("ERROR", "Error while calling listUsers API : " + err);
           reject({ code: 404, msg : err.message});
       } else {
           data.Users.forEach(function(user) {
               if (isUserASystemAdmin(user)) {
                   adminUserList.users.push(user);
               }
           });
           if (data.PaginationToken != undefined) {
                params.PaginationToken = data.PaginationToken;
                isAllowedToDeleteOrRevokeUsers(cognitoidentityserviceprovider, params, listUsers, adminUserList);
           } else {
                // We've reached the end
                let totalCognitoAdminUsers = 0;
                let totalCognitoAdminUsersToDelete = 0;  

                adminUserList.users.forEach(function(adminUser) {
                    if (isCognitoUser(adminUser)) {
                        totalCognitoAdminUsers++;
                        if (listUsers.indexOf(adminUser.Username) > -1) {
                           totalCognitoAdminUsersToDelete++;
                        }
                    }
                });

               if(totalCognitoAdminUsers != 0 && (totalCognitoAdminUsers == totalCognitoAdminUsersToDelete)) {
                   reject({ code: 404, msg : "Cannot alter last Admin User controlled by standard authentication"});
               } else {
                   console.log("Return Success");
                   resolve();
               }
           }
       }
    });
  });
};

This function is working fine when i am less than 60 users, But as per AWS Docs we can only read 60 users at a time, In that case i am sending paginationtoken in the params.

My code is getting stucked while resolve() line.

If i remove below piece of code, than it will work.

 if (data.PaginationToken != undefined) {
    params.PaginationToken = data.PaginationToken;                    
    isAllowedToDeleteOrRevokeUsers(cognitoidentityserviceprovider, params, listUsers, adminUserList);
 } 

Any help?

Please let me know if any further things are needed.

In the case of the mentioned if statement being true, you are going down a recursion of your function: isAllowedToDeleteOrRevokeUsers(…) .

You should not make recursive calls inside the promise, but resolve the promise for each page and re-execute it for each new page of the pagination.

In other words: make sure that each path in the logic inside the promise leads to a resolve() or reject() call. If your app logic requires recursion, re-structure that function, that on each recursion a new promise is created and resolved.

Can you try following code:

function isAllowedToDeleteOrRevokeUsers(cognitoidentityserviceprovider, params, listUsers, adminUserList) {
    return cognitoidentityserviceprovider.listUsers(params).promise().then((data) => {
        data.Users.forEach(function(user) {
            if (isUserASystemAdmin(user)) {
                adminUserList.users.push(user);
            }
        });
        if (data.PaginationToken != undefined) {
            params.PaginationToken = data.PaginationToken;
            return isAllowedToDeleteOrRevokeUsers(cognitoidentityserviceprovider, params, listUsers, adminUserList);
       } else {
            // We've reached the end
            let totalCognitoAdminUsers = 0;
            let totalCognitoAdminUsersToDelete = 0;  

            adminUserList.users.forEach(function(adminUser) {
                if (isCognitoUser(adminUser)) {
                    totalCognitoAdminUsers++;
                    if (listUsers.indexOf(adminUser.Username) > -1) {
                       totalCognitoAdminUsersToDelete++;
                    }
                }
            });
            if(totalCognitoAdminUsers != 0 && (totalCognitoAdminUsers == totalCognitoAdminUsersToDelete)) {
                throw new Error({ code: 404, msg : "Cannot alter last Admin User controlled by standard authentication"});
            }
            console.log("Return success");
            return;
       }
    }).catch((err) => {
        logger.log("ERROR", "Error while calling listUsers API : " + err);
        throw new Error({ code: 404, msg : err.message});
    })
}

I have done slight improvements to original code, the original code makes lot of promises which will be stuck in pending state as expect at final recurssion end condition promise is never resolved. I am using implicit promise chaining by returning promise in then block of promise, this makes all promises to chain together. Once code reached to end of recurssion then every promise in the chain will be resolved. This implementation is using pure promises so it is easy to understand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM