diff --git a/lib/layer.js b/lib/layer.js index 60a737f..2055b2b 100644 --- a/lib/layer.js +++ b/lib/layer.js @@ -65,6 +65,10 @@ Layer.prototype.handle_error = function handle_error(error, req, res, next) { return next(error) } + if (fn.constructor.name === 'AsyncFunction') { + return fn(error, req, res, next).catch(next) + } + try { fn(error, req, res, next) } catch (err) { @@ -89,6 +93,10 @@ Layer.prototype.handle_request = function handle(req, res, next) { return next() } + if (fn.constructor.name === 'AsyncFunction') { + return fn(req, res, next).catch(next) + } + try { fn(req, res, next) } catch (err) { diff --git a/test/route.js b/test/route.js index 47c8ff5..452eb7f 100644 --- a/test/route.js +++ b/test/route.js @@ -10,6 +10,7 @@ var createServer = utils.createServer var request = utils.request var shouldHitHandle = utils.shouldHitHandle var shouldNotHitHandle = utils.shouldNotHitHandle +var asyncFunctionsSupported = utils.asyncFunctionsSupported describe('Router', function () { describe('.route(path)', function () { @@ -335,6 +336,59 @@ describe('Router', function () { .get('/foo') .expect(500, 'caught: oh, no!', done) }) + + if (asyncFunctionsSupported()) { + + it('should handle errors thrown', function (done) { + var router = new Router() + var route = router.route('/foo') + var server = createServer(router) + + route.all(new Function([], + "return async function createError(req, res, next) { throw new Error('boom!') }" + )()) + + route.all(helloWorld) + + route.all(function handleError(err, req, res, next) { + res.statusCode = 500 + res.end('caught: ' + err.message) + }) + + request(server) + .get('/foo') + .expect(500, 'caught: boom!', done) + }) + + it('should handle errors thrown in error handlers', function (done) { + var router = new Router() + var route = router.route('/foo') + var server = createServer(router) + + route.all(function createError(req, res, next) { + throw new Error('boom!') + }) + + route.all(new Function([], + "return async function handleError(err, req, res, next) { throw new Error('oh, no!') }" + )()) + + route.all(function handleError(err, req, res, next) { + res.statusCode = 500 + res.end('caught: ' + err.message) + }) + + request(server) + .get('/foo') + .expect(500, 'caught: oh, no!', done) + }) + + + + } + + + }) describe('next("route")', function () { diff --git a/test/support/utils.js b/test/support/utils.js index 8841e41..3146062 100644 --- a/test/support/utils.js +++ b/test/support/utils.js @@ -12,6 +12,7 @@ exports.rawrequest = rawrequest exports.request = request exports.shouldHitHandle = shouldHitHandle exports.shouldNotHitHandle = shouldNotHitHandle +exports.asyncFunctionsSupported = asyncFunctionsSupported function createHitHandle(num) { var name = 'x-fn-' + String(num) @@ -120,3 +121,12 @@ function shouldNotHaveHeader(header) { assert.ok(!(header.toLowerCase() in res.headers), 'should not have header ' + header) } } + +function asyncFunctionsSupported() { + try { + new Function([],"return async function(){}") + return true + } catch(e) { + return false + } +}