按照生成的快递模板。在app.js
中有以下代码段
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');
});
根据我的理解,中间件将按照从app.use('/users', users)
到404处理程序到错误处理程序的顺序运行。我的问题是如何才能到达错误处理程序并执行此行res.status(err.status || 500);
?不是每个失败的请求都首先通过404处理程序,因此得到404
的状态代码?如果我错过了什么,请告诉我!谢谢
答案 0 :(得分:9)
不,它不会。如果您查看这些事件处理程序声明,您将看到未处理错误的错误处理程序,还有一个额外的err
参数:
app.use(function(req, res, next) {
app.use(function(err, req, res, next) {
错误处理中间件总是需要四个参数。您必须提供四个参数以将其标识为错误处理中间件函数。即使您不需要使用下一个对象,也必须指定它以维护签名。否则,下一个对象将被解释为常规中间件,并且将无法处理错误。有关错误处理中间件的详细信息。
因此,当找不到路由时,最后声明的中间件正在调用,它是404错误处理程序。
但是当您使用错误next
调用next(err)
或者您的代码抛出错误时,最后一个错误处理程序正在调用。
答案 1 :(得分:2)
应在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');
});
答案 2 :(得分:1)
每个失败的请求都不会先通过404处理程序,因此获取404的状态代码?
不,404路由只是一个标准的中间件,通常最后连线,这意味着如果没有其他路由处理请求,它们最终会到达404.
500是一种特殊类型的中间件,您会注意到它有4个参数(第一个是错误参数)。一旦您使用错误或任何类型的数据调用next
,就会调用此中间件。
请参阅the docs
答案 3 :(得分:0)
偶然发现本文的其他人需要注意的事情。
您要调用的最后一个中间件(如果没有被调用)-将为404,它不使用err
作为其中间件参数。因此,您不能/不应该尝试在任何其他中间件之前赶上404。因此,您的最后中间件应该不带err
参数,如下面的示例所示,当然,应该位于应用程序堆栈的底部。
//at the botton of your app.js
// catch 404.
//no err parameter
app.use(function(req, res, next) {
res.render("404Page"{
url: req.url
});
});
如果您想在进入此处理程序之前发现错误,请在此中间件之前使用(err, req, res, next)
。