Following a generated template for express. In the app.js
there is a following snippet
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
Per my understanding, the middleware will run in order from app.use('/users', users)
to 404 handler to error handler. My question is how will it be possible to reach error handler and execute this line res.status(err.status || 500);
? Wont every failed request be passed through 404 handler first and therefor getting the status code of 404
? Please let me know if I am missing something! Thank you
No, it won't. If you look at these event handlers declarations you'll see that error handler for unhandled error, has an additional err
parameter:
app.use(function(req, res, next) {
app.use(function(err, req, res, next) {
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. For details about error-handling middleware.
So, when the route is not found, the last declared middleware is calling, it's 404 error handler.
But when you call next
with error: next(err)
or your code throws an error, the last error handler is calling.
System error should be handled before 404
app.use('/users', users);
// error handler
app.use(function(err, req, res, next) {
// No routes handled the request and no system error, that means 404 issue.
// Forward to next middleware to handle it.
if (!err) return next();
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
// catch 404. 404 should be consider as a default behavior, not a system error.
app.use(function(req, res, next) {
res.status(404);
res.render('Not Found');
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With