I wrote this AppError class that will suffice my global error handling middleware in sending responses on both operational and programming errors.
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;
And here is my global error handling middleware with all necessary functions to make it work.
const AppError = require('./AppError');
//global error handling middleware all errors go into it
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'){
let error = {...err};
if(error.name === 'CastError') error = handleCastErrorDB(error);
sendErrorProd(err, res)
}
};
const sendErrorDev = (err, res) => {
res.status(err.statusCode).json({
status: err.status,
error: err,
message: err.message,
stack: err.stack
});
}
const sendErrorProd = (err, res) => {
// Operational, trusted error: send message to client
if (err.isOperational){
res.status(err.statusCode).json({
status: err.status,
message: err.message
});
}else{
// Programming or other unknown error: don't send details to client
//1_console err
console.log('error: ', err);
//2_send generic message to client
res.status(500).json({
status: 'error',
message: 'Something went very wrong!'
});
};
};
const handleCastErrorDB = err => {
const message = `Invalid ${err.path}: ${err.value}`;
return new AppError(message, 400)
};
My problem is, in the production environment when I'm trying to get the data through a GET request, the client is not getting the error that they should get, I'm testing it with the postman. Elaborating more, to test what's the client is getting I'm trying to get the data with the invalid ID...
127.0.0.1:3000/api/v1/tours/wwwwwwwwwwwwwwwwwww
That's the client mistake and therefore, they should get the response as set in handleCastErrorDB with 400 status code but instead, I'm seeing 500 status code with message
"status": "error",
"message": "Something went very wrong!"
That's the response the client would get if the error is not operational. See in sendErrorProd() function.
In development mode, I'm getting the thing I want but tucked here.
I'm in learning mode in node.js and I've tried everything in my knowledge.