DEV Community

Cover image for Wrapper function
Abayomi Ogunnusi
Abayomi Ogunnusi

Posted on

Wrapper function

Error handling in Node.js can be done using try-catch blocks, which allow you to handle exceptions thrown by your code.

However, this approach can become repetitive and verbose when dealing with multiple error-prone functions. To avoid this, you can wrap these functions in a generic error-handling function (a "wrapper function") that takes care of catching any errors and handling them in a centralized way.

For example, you could define a wrapper function that receives a function as a parameter and returns a new function that automatically handles errors:

const wrap = (fn) => (req, res, next) =>
  fn(req, res, next).catch(next);
Enter fullscreen mode Exit fullscreen mode

With this wrapper function, you can simplify your error handling code by simply wrapping your route handlers:

app.post("/shoot", wrap(async (req, res) => {
  const data = await doSomething();
  res.send(data);
}));
Enter fullscreen mode Exit fullscreen mode

Let's work with a better example.

Old code

exports.getAllTrips = async (req, res, next) => {
  try {
    const { id } = req.user;

    console.log(id);

    const trips = await Trip.find({ userId: id })
      .sort({ createdAt: -1 });
    if (!trips) return errorResMsg(res, 404, "No trips found");

    const dataInfo = {
      message: "Trips found",
      trips,
    };

    return successResMsg(res, 200, dataInfo);
  } catch (error) {
    next(error);
  }
};
Enter fullscreen mode Exit fullscreen mode

New Code

First we create wrapper function

// handle callback
const handleCallback = (callback) => {
  return async (req, res, next) => {
    try {
      await callback(req, res, next);
    } catch (error) {
      next(error);
    }
  };
};

Enter fullscreen mode Exit fullscreen mode

Then use the handleCallback to wrap the route

exports.getAllTrips = handleCallback(async (req, res) => {
  const { id } = req.user;
  const trips = await Trip.find({ userId: id }).sort({ createdAt: -1 });
  if (!trips) return errorResMsg(res, 404, "No trips found");

  const dataInfo = {
    message: "Trips found",
    trips,
  };

  return successResMsg(res, 200, dataInfo);
});
Enter fullscreen mode Exit fullscreen mode

Conclusion

Wrapper function can be utilized to streamline the try/catch block and promote DRY (Don't Repeat Yourself) principles in coding.

Top comments (9)

Collapse
 
kareemalkoul profile image
kareem alkoul • Edited

If you want to handle error in express routes, you don't need to wrap the controller with a wrapper function, just use express-async-errors and create error middleware handling for handling errors.
Look to the docs for know how to use it

Collapse
 
drsimplegraffiti profile image
Abayomi Ogunnusi

I have used this package too. Thanks for the contribution

Collapse
 
fredabod profile image
FredAbod

This was very helpful sir...

So with just that one handleCallBack function it can be applied to all the routes?

Collapse
 
drsimplegraffiti profile image
Abayomi Ogunnusi

Yes, you will just follow the same syntax as shown in the getAllTrips controller function

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
drsimplegraffiti profile image
Abayomi Ogunnusi

@abhaysinghr1 Thanks for the comment

Collapse
 
wilmela profile image
Wilmela

Great post. Makes a cleaner code.

Collapse
 
drsimplegraffiti profile image
Abayomi Ogunnusi

Thanks @wilmela. Glad it was helpful

Collapse
 
melroy89 profile image
Melroy van den Berg • Edited

I already use this, thanks very useful! Just thinking.. Can we add some kind of middle-ware code? Like how express-async-error solves it? Since we still need to repeat ourselves now on each API end-point.