Express中间件错误处理程序

时间:2017-08-20 23:43:08

标签: node.js express

按照生成的快递模板。在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的状态代码?如果我错过了什么,请告诉我!谢谢

4 个答案:

答案 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)