Global async wrapper – is this valid?

The issue we had was how to wrap all of the routes inside a router with an async wrapper (i.e. to have a global try/catch block on all controller functions) and we came up with this:

const wrapper = fn => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch(next);
};

const asyncMiddleware = (router) => {
  const routes = router;

  for (let f = 0; f < routes.stack.length; f += 1) {
    for (let fs = 0; fs < routes.stack[f].route.stack.length; fs += 1) {
      routes.stack[f].route.stack[fs].handle = wrapper(
        routes.stack[f].route.stack[fs].handle,
      );
    }
  }
  return routes;
};

module.exports = asyncMiddleware;

Then we use the “middleware” like so:

router.use('/example', AsyncMiddleware(exampleRouter));

And we have effectively wrapped all of the routes inside exampleRouter in a catch block.

I am wondering if this makes sense and/or if there is substantial problems to expect when express is upgraded/updated … etc.

Author: Fantashit

1 thought on “Global async wrapper – is this valid?

  1. Correct, I’m getting the 4.x patch ready, then merging into 5.x along with the router promise/async support for a new 5.x release. I’ll ping in here once that’s actually published to npm.

    But as for the original question, the “safest” method is to try and resist reaching into internals, even though we try not to break those. You can do this by using the router alpha (https://github.com/pillarjs/router/releases/tag/v2.0.0-alpha.1) directly and app.use(router).

Comments are closed.