Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper error handling using async/await in Node.js

I have the following code in my Node.js express app:

router.route('/user')

   .post(async function(req, res) {
       if(req.body.password === req.body.passwordConfirm) {
           try {
               var response = await userManager.addUser(req.body);
               res.status(201).send();
           } catch(err) {
               logger.error('POST /user failed with error: '+err);
               res.status(500).send({err:"something went wrong.."});
           }
       } else {
           res.status(400).send({err:'passwords do not match'});
       }
   })

and userManager:

var userManager = function() {

    this.addUser = async function(userobject) {
        userobject.password_hash = await genHash(userobject.password_hash);
        var user = new User(userobject);
        return await user.save();
    };

};

module.exports = userManager;

My question is: Will the try catch block in the route catch all errors thrown in addUser or will it only catch the ones that are thrown by user.save(), since that is the one that gets returned?

like image 438
NG. Avatar asked Jan 03 '23 06:01

NG.


1 Answers

The answer is yes, it will catch all the errors inside try block and in all internal function calls.

async/await is just syntax sugar for promises. Thus if something is possible using promises then it is also possible using async/await.

For example both of the following code snippets are equivalent:

Using promises:

function bar() {
  return Promise.reject(new Error('Uh oh!'));
}

function foo() {
  return bar();
}

function main() {
  return foo().catch(e => {
    console.error(`Something went wrong: ${e.message}`);
  });
}

main();

Using async/await:

async function bar() {
  throw new Error('Uh oh!');
}

async function foo() {
  await bar();
}

async function main() {
  try {
    await foo();
  }
  catch(e) {
    console.error(`Something went wrong: ${e.message}`);
  }
}

main();

In fact your code will not work since you don't use await on userManager.addUser.

It also forces you to use async on the parent function and that may break things up. Check express documentation (or just try if it works).

router.route('/user')

   .post(async function(req, res) {
       if(req.body.password === req.body.passwordConfirm) {
           try {
               var response = await userManager.addUser(req.body);
               res.status(201).send();
           } catch(err) {
               logger.error('POST /user failed with error: '+err);
               res.status(500).send({err:"something went wrong.."});
           }
       } else {
           res.status(400).send({err:'passwords do not match'});
       }
   })
like image 132
Jake Weary Avatar answered Jan 25 '23 13:01

Jake Weary