Search code examples
node.jsexpresstry-catch

Express - Wrapping controller functions with try-catch


I have an express backend application. The problem I have is that all the routes contains the same try-catch piece which causes code bloat in my program:

// routes.js
router.get('/', async (req, res, next) => {
  try {
    const data = extractData(req)
    await foo(data)
  } catch (err) {
    next(err)
  }
})

// controllers.js
async function foo(data) {...do smh}

As you see above, try { extractData() } catch (err) { next(err) } portion of the code exists in all of the routes defined in the app.

I tried to create a wrapper function that takes controller function as parameter and use it as:

// routes.js
router.get('/', controllerWrapper(req, res, next, foo))

// controller-wrapper.js
async function controllerWrapper(req, res, next, controllerFunc) {
  try {
    const data = extractData(req)
    await controllerFunc(data)
  } catch (err) {
    next(err)
  }
}

But this does not work due to function being invoked, and not being actually a callback.

How can I achieve this?


Solution

  • You should use a closure for this, so you can return the middleware function from controllerWrapper and use the controllerFunc inside the returned middleware

    function controllerWrapper(controllerFunc) {
          return async function (req, res, next) {
              try {
                  const data = extractData(req)
                  await controllerFunc(data)
              } catch (err) {
                 next(err)
              }
          }
    }
    
    
    router.get('/', controllerWrapper(foo))