Ad

Error Handling With Deeply Nested Async Functions

I'm having issues catching error when the functions are nested three levels deep. Here is a router with async functions:

router.post('/',
  validatevalues,
  async (req, res) => {
    // if values are invalid then
    // return res.status(422).send(errors.msg);

    const result = await userController.post(req.body);
    return res.status(201).send('Success');
  },
);

const userController = {
    async post(req) {
        try {
            await bcrypt.genSalt()
            await bcrypt.hash();
            await db.query(req.somevalues);
        }  catch (err) {
            console.error(err);
        };
    };
};
const query = {
    return new Promise(function(resolve, reject) {
      ...
      if (err) {
        reject(new Error(err));
      } else {
        resolve(res);
      };
    };
};

The console.error(err) is printing this stack trace

Error: error: duplicate key value violates unique constraint...

And then I get Uncaught AssertionError at the router level with Mocha testing:

Uncaught AssertionError: expected { Object (_events, _eventsCount, ...) } to have status code 422 but got 201

This seems expected since I am just console.error instead of throwing another newError at the controller level, but what do I need to do? If I throw another error, then wouldn't the stack trace be Error: error: error ...? This doesn't seem right to me.

Ad

Answer

You should only catch at the highest level:

  router.post('/', validatevalues, async (req, res) => {
    try {
      const result = await userController.post(req.body);
      return res.status(201).send('Success');      
    } catch(error) {
      res.status(402).send(error.message);
    }
 });

If you still want to log at a lower level, you can rethrow the error:

    }  catch (err) {
        console.error(err);
        throw err;
    } // no semicolon here, its unneccessary
Ad
source: stackoverflow.com
Ad