Search code examples
expressasync-awaitmiddleware

How to handle async errors in express using express-async-handler package?


I'm using the npm package "express-async-handler" to avoid using try/catch blocks in my route controller functions along with Express default error handler middleware. I'm also using mongoose models in the controller.

Controller code:

const getBootcamp = asyncHandler(async (req, res) => {
  const bootcamp = await Bootcamp.findById(req.params.id);

  if (bootcamp) {
    // if item found (WORKS)
    return res.status(200).json({ success: true, data: bootcamp });
  } else {
   //if item not found (WORKS) **DUE TO AN INVALID ID WHICH IS IN CORRECT FORMAT e.g. "6414eec6e5db192719b46943"**
    res.status(404);
    throw new Error('Bootcamp not found!');
  }

  //* How do I handle the situation in which an id has been passed but is not in the correct mongooseId format e.g. "6414eec6e5db192719b46943000000000000000"
});

Express Default Error Handler code:

const errorHandler = (error, req, res, next) => {
  const statusCode = res.statusCode === 200 ? 500 : res.statusCode;

  res.status(statusCode).json({ success: false, msg: error.message });
};

module.exports = errorHandler;

I have included the error middleware using app.use() after all the routes so it is configured properly.

I read that I need to call next(err) to send the error to the errorMiddleware but in the code shared above anything added after the else block with become unreachable code.


Solution

  • const errorHandler = (error, req, res, next) => {
      if (error.name === 'CastError' && error.kind === 'ObjectId') {
        return res.status(400).json({ success: false, msg: 'Invalid Id format' });
      }
    
      const statusCode = res.statusCode === 200 ? 500 : res.statusCode;
    
      res.status(statusCode).json({ success: false, msg: error.message });
    };
    
    module.exports = errorHandler;
    

    By making the above modification to the error middleware I was able to check for an invalid mongoose id and send a custom json response.

    Now 3 conditions are being handled:

    1. Query executed and data was sent successfully
    2. Query failed because the mongoose id was invalid (but in proper format)
    3. Query failed because the mongoose id was not in proper format and hence invalid

    The first 2 are handled by the controller and the last by the error handler middle.