Express中间件error handling程序

之后生成一个快速的模板。 在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处理程序到error handling程序的顺序运行。 我的问题是如何才能达到error handling程序,并执行此行res.status(err.status || 500); ? 不会每个失败的请求首先通过404处理程序,因此得到状态码404 ? 请让我知道如果我失去了一些东西! 谢谢

不,不会的 如果你看看这些事件处理程序声明,你会看到error handling程序的未处理的错误,有一个额外的err参数:

 app.use(function(req, res, next) { app.use(function(err, req, res, next) { 

error handling中间件总是需要四个参数。 您必须提供四个参数来将其标识为error handling中间件function。 即使您不需要使用下一个对象,您也必须指定它来维护签名。 否则,下一个对象将被解释为常规中间件,并且将无法处理错误。 有关error handling中间件的详细信息。

所以,当没有find路由时,最后声明的中间件正在调用,它是404error handling程序。

但是,当你调用next错误: next(err)或者你的代码抛出一个错误时,最后一个error handling程序正在调用。

不会每个失败的请求首先通过404处理程序,因此获得404的状态代码?

不,404路由只是一个标准的中间件,通常是最后一个连接,这意味着如果没有其他路由处理请求,他们最终会打到404。

500是一种特殊types的中间件,你会注意到它有4个参数(第一个是错误参数)。 这个中间件只要你next调用错误或任何types的数据就被调用。

看文档

系统错误应该在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'); });