diff --git a/package-lock.json b/package-lock.json index 590ae522..a1384182 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,8 +6,11 @@ "packages": { "": { "name": "@netlify/functions", - "version": "0.0.1", + "version": "0.1.0", "license": "MIT", + "dependencies": { + "is-promise": "^2.2.2" + }, "devDependencies": { "@commitlint/cli": "^11.0.0", "@commitlint/config-conventional": "^11.0.0", @@ -5154,8 +5157,7 @@ "node_modules/is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" }, "node_modules/is-regex": { "version": "1.1.2", @@ -13228,8 +13230,7 @@ "is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" }, "is-regex": { "version": "1.1.2", diff --git a/package.json b/package.json index 597fc931..6e79abef 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,9 @@ "directories": { "test": "test" }, - "dependencies": {}, + "dependencies": { + "is-promise": "^2.2.2" + }, "devDependencies": { "@commitlint/cli": "^11.0.0", "@commitlint/config-conventional": "^11.0.0", diff --git a/src/lib/builder_functions.js b/src/lib/builder_functions.js index b9e4e47a..ec843350 100644 --- a/src/lib/builder_functions.js +++ b/src/lib/builder_functions.js @@ -1,3 +1,5 @@ +const isPromise = require('is-promise') + const { HTTP_STATUS_METHOD_NOT_ALLOWED, HTTP_STATUS_OK } = require('./consts') const augmentResponse = (response) => { @@ -12,19 +14,24 @@ const augmentResponse = (response) => { } // eslint-disable-next-line promise/prefer-await-to-callbacks -const wrapHandler = (handler) => async (event, context, callback) => { +const wrapHandler = (handler) => (event, context, callback) => { if (event.httpMethod !== 'GET' && event.httpMethod !== 'HEAD') { - return { + return Promise.resolve({ body: 'Method Not Allowed', statusCode: HTTP_STATUS_METHOD_NOT_ALLOWED, - } + }) } // eslint-disable-next-line promise/prefer-await-to-callbacks const wrappedCallback = (error, response) => callback(error, augmentResponse(response)) - const response = await handler(event, context, wrappedCallback) + const execution = handler(event, context, wrappedCallback) + + if (isPromise(execution)) { + // eslint-disable-next-line promise/prefer-await-to-then + return execution.then(augmentResponse) + } - return augmentResponse(response) + return execution } module.exports = { builderFunction: wrapHandler } diff --git a/test/builder_functions.js b/test/builder_functions.js index 61932aa5..5880c34e 100644 --- a/test/builder_functions.js +++ b/test/builder_functions.js @@ -132,3 +132,21 @@ test('Returns a 405 error for requests using the PATCH method', async (t) => { t.deepEqual(response, { body: 'Method Not Allowed', statusCode: 405 }) }) + +test('Preserves errors thrown inside the wrapped handler', async (t) => { + const error = new Error('Uh-oh!') + + error.someProperty = ':thumbsdown:' + + const myHandler = async () => { + const asyncTask = new Promise((resolve) => { + setTimeout(resolve, 0) + }) + + await asyncTask + + throw error + } + + await t.throwsAsync(invokeLambda(builderFunction(myHandler)), { is: error }) +})