diff --git a/lib/view.js b/lib/view.js index 6f62472075..e1fa35f830 100644 --- a/lib/view.js +++ b/lib/view.js @@ -16,7 +16,7 @@ var utils = require('keystone-utils'); * @api public */ -function View (req, res) { +function View (req, res, next) { if (!req || req.constructor.name !== 'IncomingMessage') { throw new Error('Keystone.View Error: Express request object is required.'); @@ -28,6 +28,7 @@ function View (req, res) { this.req = req; this.res = res; + this.next = next; this.initQueue = []; // executed first in series this.actionQueue = []; // executed second in parallel, if optional conditions are met @@ -367,7 +368,11 @@ View.prototype.render = function (renderFn, locals, callback) { throw new Error('Keystone.View.render() events must be functions.'); } }, function (err) { - renderFn(err, req, res); - }); + if (err && this.next) { + this.next(err); + } else { + renderFn(err, req, res); + } + }.bind(this)); }; diff --git a/test/unit/lib/view.js b/test/unit/lib/view.js index 280f85bc2b..f329bc627c 100644 --- a/test/unit/lib/view.js +++ b/test/unit/lib/view.js @@ -83,6 +83,32 @@ describe('Keystone.View', function () { .expect('OK', done); }); + it('must return control to the next middleware on method errors', function(done){ + var app = getApp(); + app.get('/', function(req, res, next) { + var view = new keystone.View(req, res, next); + view.on('init', function(next){ + var err = new Error('Not Found'); + err.status = 404; + next(err); + }); + view.render(function() { + var err = new Error('must not call render'); + done(err); + }); + }); + app.use(function(err,req,res,next){ + if(err && err.status === 404){ + res.status(404).send('Not Found'); + } else { + done('error should be handled'); + } + }); + request(app) + .get('/') + .expect(404, done) + }); + function getApp_getAndPost() { var app = getApp(); app.all('/', function (req, res) {