Problem:
I defined my app routes in that order
app.use(express.json());
app.use(express.static(`${__dirname}/public`));
app.use('/api/v1/tours', tourRouter);
app.use('/api/v1/users', userRouter);
app.all('*', (req, res, next) => {
const error = new AppError(
`This ${req.originalUrl} is not on the server`,
404,
);
next(error);
});
app.use(globalErrorHandler);
The AppError is a class to customize the error object and the globalErrorHandler is function that send the error response according to the error object comes from next()
.
My problem is that the ‘*’ routes runs with all the routes that I handled previous with the tourRouter. I don’t know why this happens. It wasn’t doing this, just happens once and still happening until the time I wrote this problem.
NOTE: Postman gives me the correct response from the routes I defined, but the terminal in VSC gives me the “cannot send header after it sent” error.
I don’t know what to do since I don’t know why the error happened.
Solution:
I’ve discovered the error which was that I rapped my async router handler functions with a function called catchAsync()
module.exports = function (fn) {
return (req, res, next) => {
fn(req, res, next).then(next);
}
}
I’ve updated this function to be this
module.exports = function (fn) {
return (req, res, next) => {
try {
fn(req, res, next);
} catch (error) {
next(error);
}
};
};
I made this because the catchAsync function calls the next after the fn() ends which causes to run the next middleware in the stack which is globalErrorHandler
app.use(globalErrorHandler);
to run and send another response and from here the error happened
But what makes me still confused is that the code works fine and then starts throwing errors