diff --git a/History.md b/History.md index bf7764011b..824f2443d3 100644 --- a/History.md +++ b/History.md @@ -2,6 +2,7 @@ unreleased ========== * Add debug message when loading view engine + * Add `next("router")` to exit from router * Fix case where `router.use` skipped requests routes did not * Remove usage of `res._headers` private field - Improves compatibility with Node.js 8 nightly diff --git a/lib/router/index.js b/lib/router/index.js index 917c6002c8..1f426068d7 100644 --- a/lib/router/index.js +++ b/lib/router/index.js @@ -191,6 +191,12 @@ proto.handle = function handle(req, res, out) { removed = ''; } + // signal to exit router + if (layerError === 'router') { + setImmediate(done, null) + return + } + // no more matching layers if (idx >= stack.length) { setImmediate(done, layerError); diff --git a/lib/router/route.js b/lib/router/route.js index 1ec9d50ea0..ea82ed29df 100644 --- a/lib/router/route.js +++ b/lib/router/route.js @@ -112,10 +112,16 @@ Route.prototype.dispatch = function dispatch(req, res, done) { next(); function next(err) { + // signal to exit route if (err && err === 'route') { return done(); } + // signal to exit router + if (err && err === 'router') { + return done(err) + } + var layer = stack[idx++]; if (!layer) { return done(err); diff --git a/test/app.router.js b/test/app.router.js index 1bba62e270..e838b2e33f 100644 --- a/test/app.router.js +++ b/test/app.router.js @@ -932,6 +932,37 @@ describe('app.router', function(){ }) }) + describe('when next("router") is called', function () { + it('should jump out of router', function (done) { + var app = express() + var router = express.Router() + + function fn (req, res, next) { + res.set('X-Hit', '1') + next('router') + } + + router.get('/foo', fn, function (req, res, next) { + res.end('failure') + }) + + router.get('/foo', function (req, res, next) { + res.end('failure') + }) + + app.use(router) + + app.get('/foo', function (req, res) { + res.end('success') + }) + + request(app) + .get('/foo') + .expect('X-Hit', '1') + .expect(200, 'success', done) + }) + }) + describe('when next(err) is called', function(){ it('should break out of app.router', function(done){ var app = express()