简体   繁体   中英

how to return error from async/await inside promises

i initially wrote the code with promises, but due to a for loop had to use async/await.

the code works now, but i don't know how to throw the error which can work equivalent to reject of promise.

let createGroup=(data)=>{
                return new Promise((resolve,reject)=>{
                    if(check.isEmpty(data.groupName)){
                        reject('GroupId not Valid');
                    }
                    else{
                        let newGroup= new ExpenseModel({
                            groupId:'G-'+shortid.generate(),
                            groupName:data.groupName,
                            contributors:data.contributorObjIds,
                            timeCreated:time.now().format(),
                            creator:data.ownerId
                        })
                        newGroup.save((err,group)=>{
                            if(err){
                                reject(`Group Not Created ${err}`);
                            }else{
                                data.groupdata=group;
                                console.log("group created",data);
                                resolve(data);
                            }
                        })
                    }
                })
            }

            let updateUserData= async (data)=>{
                try{
                    for(user of data.contributorIds){
                        const res=await UserModel.findOne({'userId':user});
                        res.groups.push(data.groupdata._id);
                        const resSave=await res.save();
                        let id='GroupCreated'+user;

                        eventEmitter.emit('getGroup',user);    
                    }

                    return 1;
                }
                catch(e){
                    return e;
                }
            }



            createGroup(data)
            .then(updateUserData)
            .then((resolve)=>{
                let apiResponse = response.generate(false, 'Group created', 200, resolve);
                console.log(apiResponse);
            })
            .catch((err)=>{
                let apiResponse = response.generate(true, 'Group not saved', 400, null);
                console.log('group creation failed',err);
                 res.send(apiResponse);
            })

here in updateUserData how to check for errors while fetching data from db. so that it finally goes to the catch block of the promise. and apiResponse of error is called.

i don't know how to throw the error which can work equivalent to reject of promise.

Well, you should throw it not return it:-) Exceptions in an async function will cause the returned promise to reject.

async function updateUserData(data) {
    try {
        for (user of data.contributorIds) {
            const res = await UserModel.findOne({'userId':user});
            res.groups.push(data.groupdata._id);
            const resSave = await res.save();
            let id = 'GroupCreated'+user;
            eventEmitter.emit('getGroup', user);
        }
        return 1;
    } catch(e){
        throw e;
//      ^^^^^
    }
}

However, catching an error with try / catch only to rethrow it without doing anything else is pointless, you should just let the exception bubble. Simplify to

async function updateUserData(data) {
    for (user of data.contributorIds) {
        const res = await UserModel.findOne({'userId':user});
        res.groups.push(data.groupdata._id);
        const resSave = await res.save();
        let id = 'GroupCreated'+user;
        eventEmitter.emit('getGroup', user);
    }
    return 1;
}

In a regular try..catch we can analyze the error and maybe rethrow it if can't handle. The same thing is possible for promises.

If we throw inside .catch , then the control goes to the next closest error handler. And if we handle the error and finish normally, then it continues to the closest successful.then handler.

In the example below the .catch successfully handles the error:

new Promise((resolve, reject) => {

  throw new Error("Whoops!");

}).catch(function(error) {

  alert("The error is handled, continue normally");

}).then(() => alert("Next successful handler runs"));

But inside each catch, we can trowing a new error if it remains unhandled, we can make sure it doesn't block the code and also return it at last.

// the execution: catch -> catch -> then
new Promise((resolve, reject) => {

  throw new Error("Whoops!");

}).catch(function(error) { // (*)

  if (error instanceof MyCustomEror) {
    // handle it
  } else {
    alert("Can't handle such error");

    throw error; // throwing this or another error jumps to the next catch
  }

}).then(function() {
  /* doesn't run here */
}).catch(error => { // (**)

  alert(`The unknown error has occurred: ${error}`);
  // don't return anything => execution goes the normal way

});

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