Khairul Habib
Khairul Habib

Reputation: 471

Express Try and Catch in Form of middleware

i'm working on node.js using Express to built a backend. i'm intended to handle status 500 error that may happened.

router.put('/test', async (req, res) => {
    try {
      return res.send(await request.updateTest(req.body, 1))
    } catch(err) {
        console.log(err)
        return res.status(500).send(err.stack)
    }
})

this is my example of the code. it's do work perfectly. but when i'm try to make unknown error from the database query, i want to log the error and return status 500 as response with the error detail.

but i'll need to add try and catch every time i'm build a new controller/routes

is there anyway i could express them in form of middleware instead of write try and catch everytime?

this is an example of code i've try to make it as middleware but it's has no work and no effect when called.

error.js

module.exports = function (err, req, res, next) {
    console.log(err)
    res.status(500).send({
        error: 'Internal Server Error',
        message: err.stack
    })
    next(err)
}

main.js

const errorHandler = require('./error')
const { corsOption } = require('./cors')
const cors = require('cors')
const test = require('./test')


module.exports = function (app) {
    app.use(cors(corsOption))
    app.use(errorHandler)
    app.use('/api/test', test)
}

is there anyway that i can do for this to work?

Upvotes: 3

Views: 9477

Answers (2)

Ariel
Ariel

Reputation: 1436

Your global error handler should be placed after all other middlewares/routes:

app.use(middleware)
// all other middlewares

app.use('/api/test', test)
// all other routes

// error handler
app.use(function (err, req, res, next) {
  res.status(500).json({
    error: err.message,
  });
});

To avoid adding try/catch to everything, better to wrap your route handler to catch the errors (asyncWrapper):

app.use(middleware)
// all other middlewares


const asyncWrapper = (cb) => {
  return (req, res, next) => cb(req, res, next).catch(next);
};

const test = async (req, res) => {
  return res.send(await request.updateTest(req.body, 1))
}

// wrap your handler to catch errors (Async functions return a promise)
app.use('/api/test', asyncWrapper(test))
// all other routes

// error handler
app.use(function (err, req, res, next) {
  res.status(500).json({
    error: err.message,
  });
});

Upvotes: 9

Rajesh Verma
Rajesh Verma

Reputation: 307

There are two approaches to resolve unhandled exceptions in Node.js

  1. Using try-catch blockwhich is already you are using

  2. Using Process i.e use Process to handle exception. A process is a global object that provides information about the current Node.js process. The process is a listener function that is always listening to the events. The most effective and efficient approach is to use Process. If any uncaught or unhandled exception occurs in your code flow, that exception will be caught in code

    process.on('uncaughtException', function(err) {
    
     // Handle the error safely
     console.log(err)
    })
    

The above code will be able to handle any sort of unhandled exception which occurs in Node.js. see this Process Events

Upvotes: 0

Related Questions