From d8f29224030ac10a3954982e5ceed9b61cc21b37 Mon Sep 17 00:00:00 2001 From: Max Bladen-Clark Date: Thu, 19 Jul 2018 20:21:45 +0100 Subject: [PATCH 1/2] Add support for throwing in async handlers. --- lib/layer.js | 8 +++++++ test/route.js | 54 +++++++++++++++++++++++++++++++++++++++++++ test/support/utils.js | 10 ++++++++ 3 files changed, 72 insertions(+) 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..5e719e9 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 + } +} From 6d8e225eaba644ba10e4d5acfd3e012c94d22c0a Mon Sep 17 00:00:00 2001 From: Max Bladen-Clark Date: Fri, 20 Jul 2018 10:09:19 +0100 Subject: [PATCH 2/2] remove semi-colon --- test/support/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/support/utils.js b/test/support/utils.js index 5e719e9..3146062 100644 --- a/test/support/utils.js +++ b/test/support/utils.js @@ -124,7 +124,7 @@ function shouldNotHaveHeader(header) { function asyncFunctionsSupported() { try { - new Function([],"return async function(){}"); + new Function([],"return async function(){}") return true } catch(e) { return false