Node js Error Handler Doesnt get exact error message from Controller Express/Mongoose

Viewed 123

I a trying to implement a rest API for our project then I go for node js and express. I have built all the models and controllers. I faced an issue while trying to handle an error. Errorhandler function doesn't receive all the properties of error that caught in try/catch block. I can not read its name in a handler but I can use its name in the controller. Could you please help me?

const errorHandler = (err, req, res, next) => {
  console.log(`Error in method:${req.method}: ${err.stack}`.bgRed);

  let error = { ...err };

  console.log(`Error handler: ${err.name}`);

  res.status(error.statusCode || 500).json({
    success: false,
    data: error.message || 'Server Error',
  });
};

module.exports = errorHandler;

controller

const mongoose = require('mongoose');
const Product = require('../models/Product');
const ErrorResponse = require('../utils/error');

const routeName = 'PRODUCT';

// @desc     getting single product via id
// @route    GET api/v1/products
// @acces    public
exports.getProdcut = async (req, res, next) => {
  try {
    const product = await Product.findById(req.params.id);

    if (!product) {
      return next(
        new ErrorResponse(`Product not found with id:${req.params.id}`, 404)
      );
    }

    res.status(200).json({
      success: true,
      data: product,
    });
  } catch (err) {
    console.log(err.name);
    console.log('ERRO APPEND');
    next(new ErrorResponse(`Product not found with id:${req.params.id}`, 404));
  }
};
1 Answers

Assuming that errorHandler is part of your middleware that is somewhere after getProdcut, you can try just throwing the error and Express will automatically detect that for you, because error handling middleware such as yours accepts 4 parameters. So the following would work:

const getProdcut = async (req, res, next) => {
  try {
    // ...
  } catch (err) {
    throw err;
  }
};

const errorHandler = (err, req, res, next) => {
  if (err) {
     console.log('hello from the error middleware');
     console.log(err.name);
  }
  else {
     // next() or some other logic here
  }
}

app.use('/yourRoute', getProdcut, errorHandler);

And inside of your errorHandler you should have access to the error object.

Error-handling middleware always takes four arguments. You must provide four arguments to identify it as an error-handling middleware function. Even if you don’t need to use the next object, you must specify it to maintain the signature. Otherwise, the next object will be interpreted as regular middleware and will fail to handle errors.

https://expressjs.com/en/guide/using-middleware.html#middleware.error-handling

Related