diff --git a/lib/application.js b/lib/application.js index 3a412a5..68b69fc 100644 --- a/lib/application.js +++ b/lib/application.js @@ -125,7 +125,7 @@ app.callback = function(){ var ctx = new self.Context(self, req, res); function done(err) { - if (err) ctx.error(err); + if (err) ctx.onerror(err); } co.call(ctx, function *(){ @@ -134,6 +134,17 @@ app.callback = function(){ } }; +/** + * Default error handler. + * + * @param {Error} err + * @api private + */ + +app.onerror = function(err){ + if (this.outputErrors) console.error(err.stack); +}; + /** * Response middleware. */ diff --git a/lib/context.js b/lib/context.js index faece14..e465e8a 100644 --- a/lib/context.js +++ b/lib/context.js @@ -545,10 +545,20 @@ module.exports = { * @api private */ - error: function(err){ - if (this.app.outputErrors) console.error(err.stack); - // TODO: change name - // TODO: header sent check + onerror: function(err){ + // nothing we can do here other + // than delegate to the app-level + // handler and log. + if (this.headerSent) return this.app.onerror(err); + + // err.status support + if (err.status) { + this.status = err.status; + this.res.end(http.STATUS_CODES[err.status]); + return; + } + + // respond this.status = 500; this.res.end('Internal Server Error'); }, diff --git a/test/application.js b/test/application.js index 3e4d68b..b93a0f5 100644 --- a/test/application.js +++ b/test/application.js @@ -205,6 +205,25 @@ describe('app.respond', function(){ }) describe('when an error occurs', function(){ + describe('with a .status property', function(){ + it('should respond with .status', function(done){ + var app = koa(); + + app.use(function(next){ + return function *(){ + var err = new Error('s3 explodes'); + err.status = 403; + throw err; + } + }); + + request(app.listen()) + .get('/') + .expect(403, 'Forbidden') + .end(done); + }) + }) + it('should respond with 500', function(done){ var app = koa();