error handling中间件并不总是工作
我正在使用Express构build一个示例网站,我碰到一些我不太明白的东西。
如果我理解正确,error handling中间件应该是pipe道中的最后一个。 例如,工作得很好:
var http = require('http'); var express = require('express'); var app = express(); app.set('view engine', 'jade'); app.set('views', './views'); app.use(express.static('./public')); http.createServer(app).listen(portNumber, function() { }); app.get('/hello', function(req, res) { res.send('Welcome!'); }); app.use(function(err, req, res, next) { res.status(500).send('something broke!'); }); app.get('/error', function(req, res, next) { somethingNonExistent(2016); });
但是,如果我在http.createServer调用之前注册了中间件,但在所有其他中间件注册之后,它将不起作用 – 我的代码不会被调用:
var http = require('http'); var express = require('express'); var app = express(); app.use(express.static('./public')); app.use(function(err, req, res, next) { res.status(500).send('something broke!'); }); http.createServer(app).listen(portNumber, function() { }); app.get('/hello', function(req, res) { res.send('Welcome!'); }); app.get('/error', function(req, res, next) { somethingNonExistent(2016); });
我在这里错过了什么? 我的猜测是,app.get调用内部使用一些中间件,它会变得混乱。
我使用Express 3.2.6和Node.js 0.10.29,如果这有什么区别的话
在定义路由/中间件时,将使用您指定的path
来查看它是否与传入的请求相匹配。 您的请求将始终被路由到第一场比赛。 一个请求可能有多个匹配,所以顺序很重要。 您可以通过调用next()
函数来匹配下一个匹配的路由/中间件。
当使用app.use
装载中间件而不指定path时,每个path都有资格打中间件。 所以,如果这是您首先安装的,那么每个请求都将使用该中间件。
如果你想捕获所有的error handling程序,你会想要相反的 – 你应该在你的路由定义的最后安装中间件。 您需要调用处理程序中的next
函数来实际访问这个中间件:
app.get('/hello', function(req, res, next) { ... // Let's pretend that there was some error next() }); // After all of your route definitions... app.use(function(req, res) { res.status(500).send('something broke!'); })
请注意,如果当前path不存在路由,那么您也将碰到所有中间件。
文件
http://expressjs.com/en/guide/error-handling.html
你最后定义error handling中间件,在其他app.use()和路由调用之后; 例如:
var bodyParser = require('body-parser'); var methodOverride = require('method-override'); app.use(bodyParser()); app.use(methodOverride()); app.use(function(err, req, res, next) { // logic });
内置的
为了便于理解,你可以想象pipe道。 当你的控制器收到一个请求,在Express中,看起来像这样
try { fn(req, res, next); // your controller } catch (err) { next(err); }
那么,那么你的代码就会抛出错误, next
就会调用err
。 基本上和next(new Error())
调用一样next(new Error())
。 之后,表示试着在中间件pipe道中find具有4个参数的下一个中间件。 在你的情况下, 在你的黑幕控制器之前声明的error handling程序,所以他不参与。
从技术上讲,控制器和中间件没有区别。 或者,您可以传入控制器的next
参数,并调用它以进一步通过pipe道。 如果你没有调用next()
,你完成处理请求。
- 如果您已经定义了快速路线,为什么要创buildAngular路线?
- 如何使用Underscore.js作为View Engine for Express v3
- 使用Express.js提供纯文本SVG(与Cheerio.js相关的解决scheme)
- 使用express和socket.io节点js – 找不到socket.io.js
- grunt.task.run()不起作用
- 快速会话中req.sessionID和req.session.id之间的区别
- 护照js如何configuration某人保持login状态?
- 为什么socket.io使用不同的path创build第二个“sid”cookie?
- 如何在Node.js(express)上返回由{}而不是包围的json返回使用knex和postgresql的查询结果