node.jsmongodbexpress

Getting isOperational undefined when handelling production error


I am creating a Natours project, I want to handle operational errors that occurs in development and production environment separately.

Here is my appError.js

class AppError extends Error {
  constructor(message, statusCode) {
    super(message);

    this.statusCode = statusCode;
    this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
    this.isOperational = true;

    Error.captureStackTrace(this, this.constructor);
  }
}

module.exports = AppError;

Here is my errorControllers.js

const AppError = require('../utils/appError');

const handleCastErrorDB = (err) => {
  const message = `Invalid ${err.path}: ${err.value}`;
  return new AppError(message, 400);
};

const sendErrorDev = (err, res) => {
  res.status(err.statusCode).json({
    status: err.status,
    error: err,
    message: err.message,
    stack: err.stack,
  });
};

const sendErrorProd = (err, res) => {
  // Operation, trusted error: send message to Client
  // console.log(err.isOperational);
  if (err.isOperational) {
    res.status(err.statusCode).json({
      status: err.status,
      message: err.message,
    });
    // Programming or other unkown error happened: don't leak error details
  } else {
    // Log error in the console
    console.log('💥ERROR: ', err);
    // Send error to the user
    res.status(500).json({
      status: 'error',
      message: 'Something wrong happened.',
    });
  }
};

module.exports = (err, req, res, next) => {
  err.statusCode = err.statusCode || 500;
  err.status = err.status || 'error';

  if (process.env.NODE_ENV === 'development') {
    sendErrorDev(err, res);
  } else if (process.env.NODE_ENV === 'production') {
    // eslint-disable-next-line node/no-unsupported-features/es-syntax
    let error = { ...err };

    if (error.name === 'Cast') error = handleCastErrorDB(error);
    sendErrorProd(error, res);
  }

  next();
};

I have created a seperate appError class and errorController file. So when any error occurs depending on whether the environment is development and production it would throw error. But it is giving isOperational property of error object in sendErrorProd function 'undefined'.

Can you help me with the error that is occuring in my code.


Solution

  • First of all, make sure that you're really testing for a CastError not some other error in your postman.

    Secondly, be sure that you're on the production environment.

    After clarifying the first and the second step, please try this following code..

    else if (process.env.NODE_ENV === 'production') {
            let error = {...err};
    
            if (err.name === 'CastError')   error = handleCastErrorDB(error);
        
            sendErrorProd(error, res);
        }
    

    keep in mind that you're doing destructuring for an internal express error variable so, there might be some confusion within variables.

    Hope it Works 😀.