Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are nested catches within promises required?

We would like to reduce the number of catch blocks inside our promises. If we remove the nested catches, will exceptions bubble up to the parent catch?

temporaryUserModel.findOne({email: req.body.email})     .then(tempUser => {         if (tempUser) {             temporaryUserModel.findOneAndUpdate({_id: tempUser.toJSON()._id}, user)                 .then((doc) => {                     return res.status(200).json({                         status: 'Success',                         data: {url: planOpted.chargifySignupUrl}                     });                 })                 .catch(err => error(err, res));         } else {             temporaryUserModel(user).save()                 .then((doc) => {                     return res.status(200).json({                         status: 'Success',                         data: {url: planOpted.chargifySignupUrl}                     });                 })                 .catch(err => error(err, res));         }     })     .catch(err => error(err, res)); 

We'd like to remove the two nested catches and keep only the catch at the bottom. Is this ok?

like image 667
wayofthefuture Avatar asked Dec 26 '16 22:12

wayofthefuture


People also ask

How do you handle nested promises?

In a promise nesting when you return a promise inside a then method, and if the returned promise is already resolved/rejected, it will immediately call the subsequent then/catch method, if not it will wait. If promised is not return, it will execute parallelly.

How does catch work in promises?

catch " around the executor automatically catches the error and turns it into rejected promise. This happens not only in the executor function, but in its handlers as well. If we throw inside a . then handler, that means a rejected promise, so the control jumps to the nearest error handler.

Does await resolve nested promises?

All that is needed is to mark your async function with the async keyword. This enables you to use the await keyword to resolve promises for you! The async/await mechanism for control flow is an extremely powerful way to reason about anything asynchronous within your app.

Can we use try catch in promise?

You cannot use try-catch statements to handle exceptions thrown asynchronously, as the function has "returned" before any exception is thrown. You should instead use the promise. then and promise. catch methods, which represent the asynchronous equivalent of the try-catch statement.


2 Answers

No, they won't. They only bubble up to the result promise if you chain your promises, for which you need to return the inner promises created by the callbacks. Otherwise the outer promise cannot wait for them and will not know when/how they resolve (whether they fulfill or reject).

temporaryUserModel.findOne({email: req.body.email}).then(tempUser => {     if (tempUser) {         return temporaryUserModel.findOneAndUpdate({_id: tempUser.toJSON()._id}, user); //      ^^^^^^     } else {         return temporaryUserModel(user).save(); //      ^^^^^^     } }).then((doc) => { // no need to duplicate this code when you chain anyway     return res.status(200).json({         status: 'Success',         data: {url: planOpted.chargifySignupUrl}     }); }).catch(err => error(err, res)); 
like image 107
Bergi Avatar answered Oct 13 '22 00:10

Bergi


You can extract some of the logic into separate functions, and return the inner promises to bubble up any exceptions to the promise chain:

temporaryUserModel.findOne({email: req.body.email})   .then(updateTempUser)   .then(formatResponse)   .catch(err => error(err, res));  function updateTempUser(tempUser) {   if (tempUser) {     return temporaryUserModel.findOneAndUpdate({         _id: tempUser.toJSON()._id     }, user);   } else {     return temporaryUserModel(user).save()   } }  function formatResponse(doc) {   return res.status(200).json({     status: 'Success',     data: {url: planOpted.chargifySignupUrl}   }); } 
like image 20
hackerrdave Avatar answered Oct 13 '22 00:10

hackerrdave