Comparing version 0.2.18 to 0.3.0
{ | ||
"name": "middy", | ||
"version": "0.2.18", | ||
"version": "0.3.0", | ||
"description": "The simple (but cool 😎) middleware engine for AWS lambda in Node.js", | ||
@@ -35,2 +35,4 @@ "main": "src/index.js", | ||
"devDependencies": { | ||
"babel-jest": "^21.2.0", | ||
"babel-preset-env": "^1.6.1", | ||
"codecov": "^3.0.0", | ||
@@ -46,3 +48,4 @@ "eslint": "^4.4.1", | ||
"jsdoc": "^3.5.5", | ||
"jsdoc-to-markdown": "^3.0.0" | ||
"jsdoc-to-markdown": "^3.0.0", | ||
"regenerator-runtime": "^0.11.0" | ||
}, | ||
@@ -49,0 +52,0 @@ "dependencies": { |
@@ -26,12 +26,14 @@ <div align="center"> | ||
</a> | ||
<a href="https://greenkeeper.io/"> | ||
<img src="https://badges.greenkeeper.io/middyjs/middy.svg" alt="Greenkeeper badge" style="max-width:100%;"> | ||
</a> | ||
<a href="https://gitter.im/middyjs"> | ||
<img src="https://badges.gitter.im/gitterHQ/gitter.svg" alt="Chat on Gitter" style="max-width:100%;"> | ||
</a> | ||
<a href="https://greenkeeper.io/"> | ||
<img src="https://badges.greenkeeper.io/middyjs/middy.svg" alt="Greenkeeper badge" style="max-width:100%;"> | ||
</a> | ||
</p> | ||
</div> | ||
## TOC | ||
- [A little appetizer](#a-little-appetizer) | ||
@@ -251,2 +253,41 @@ - [Install](#install) | ||
### Async Middlewares | ||
Middy supports middlewares that return promises instead that directly calling the callback: | ||
```javascript | ||
const asyncValidator = () => { | ||
before: (handler) => { | ||
if (handler.event.body) { | ||
return new Promise((resolve, reject) => { | ||
// async validation logic | ||
}) | ||
} | ||
return Promise.resolve() | ||
} | ||
} | ||
handler.use(asyncValidator()) | ||
``` | ||
Thanks to this behaviour you can define middlewares using `async` functions: | ||
```javascript | ||
const asyncValidator = () => { | ||
before: async (handler) => { | ||
if (handler.event.body) { | ||
return await asyncValidate(handler.event.body) | ||
} | ||
return | ||
} | ||
} | ||
handler.use(asyncValidator()) | ||
``` | ||
Of course, since AWS lambda runs on Node.js 6.10, you will need to transpile your `async/await` code (e.g. using [babel](https://babeljs.io/)). | ||
## Writing a middleware | ||
@@ -445,3 +486,3 @@ | ||
| onError | [<code>middlewareAttachFunction</code>](#middlewareAttachFunction) | attach a new *error-handler-only* middleware | | ||
| __middlewares | <code>Object</code> | contains the list of all the attached middlewares organised by type (`before`, `after`, `onError`). To be used only for testing and debugging purposes | | ||
| __middlewares | <code>Object</code> | contains the list of all the attached middlewares organised by type (`before`, `after`, `onError`). To be used only for testing and debugging purposes | | ||
@@ -448,0 +489,0 @@ <a name="useFunction"></a> |
@@ -407,2 +407,105 @@ const middy = require('../middy') | ||
}) | ||
test('It should handle async middlewares', (endTest) => { | ||
const asyncBefore = async (handler) => { | ||
handler.event.asyncBefore = true | ||
} | ||
const asyncAfter = async (handler) => { | ||
handler.event.asyncAfter = true | ||
} | ||
const handler = middy((event, context, callback) => { | ||
return callback(null, {some: 'response'}) | ||
}) | ||
handler | ||
.before(asyncBefore) | ||
.after(asyncAfter) | ||
handler({}, {}, (err, response) => { | ||
expect(err).toBe(null) | ||
expect(handler.event.asyncBefore).toBeTruthy() | ||
expect(handler.event.asyncAfter).toBeTruthy() | ||
endTest() | ||
}) | ||
}) | ||
test('It should handle async error middlewares', (endTest) => { | ||
const expectedError = new Error('Error in handler') | ||
const asyncOnError = async (handler) => { | ||
handler.error = null | ||
handler.response = {result: 'The error is handled'} | ||
} | ||
const handler = middy((event, context, callback) => { | ||
return callback(expectedError) | ||
}) | ||
handler | ||
.onError(asyncOnError) | ||
handler({}, {}, (err, response) => { | ||
expect(err).toBe(null) | ||
expect(response).toEqual({result: 'The error is handled'}) | ||
endTest() | ||
}) | ||
}) | ||
test('A middleware that return a non-promise should trigger an error', (endTest) => { | ||
const beforeMiddleware = (handler) => { | ||
return 'this is not a promise' | ||
} | ||
const handler = middy((event, context, callback) => { | ||
return callback(null, {foo: 'bar'}) | ||
}) | ||
handler | ||
.before(beforeMiddleware) | ||
handler({}, {}, (err, response) => { | ||
expect(err.message).toBe('Unexpected return value in middleware') | ||
endTest() | ||
}) | ||
}) | ||
test('An error middleware that return a non-promise should trigger an error', (endTest) => { | ||
const onErrorMiddleware = (handler) => { | ||
return 'this is not a promise' | ||
} | ||
const handler = middy((event, context, callback) => { | ||
throw new Error('something happened') | ||
}) | ||
handler | ||
.onError(onErrorMiddleware) | ||
handler({}, {}, (err, response) => { | ||
expect(err.message).toBe('Unexpected return value in onError middleware') | ||
expect(err.originalError.message).toBe('something happened') | ||
endTest() | ||
}) | ||
}) | ||
// see issue #49 (https://github.com/middyjs/middy/issues/49) | ||
test('Handles error thrown in async functions', (endTest) => { | ||
const beforeMiddleware = async (handler) => { | ||
throw new Error('I am throwing in an async func') | ||
} | ||
const handler = middy((event, context, callback) => { | ||
return callback(null, {foo: 'bar'}) | ||
}) | ||
handler | ||
.before(beforeMiddleware) | ||
handler({}, {}, (err, response) => { | ||
expect(err.message).toBe('I am throwing in an async func') | ||
endTest() | ||
}) | ||
}) | ||
}) |
@@ -0,1 +1,3 @@ | ||
const isPromise = require('./isPromise') | ||
/** | ||
@@ -11,3 +13,3 @@ * @typedef middy | ||
* @property {middlewareAttachFunction} onError - attach a new *error-handler-only* middleware | ||
* @property {Object} __middlewares - contains the list of all the attached | ||
* @property {Object} __middlewares - contains the list of all the attached | ||
* middlewares organised by type (`before`, `after`, `onError`). To be used only | ||
@@ -59,3 +61,15 @@ * for testing and debugging purposes | ||
if (nextMiddleware) { | ||
return nextMiddleware(instance, runNext) | ||
const retVal = nextMiddleware(instance, runNext) | ||
if (retVal) { | ||
if (!isPromise(retVal)) { | ||
throw new Error('Unexpected return value in middleware') | ||
} | ||
retVal | ||
.then(runNext) | ||
.catch(done) | ||
} | ||
return | ||
} | ||
@@ -84,3 +98,18 @@ | ||
if (nextMiddleware) { | ||
return nextMiddleware(instance, runNext) | ||
const retVal = nextMiddleware(instance, runNext) | ||
if (retVal) { | ||
if (!isPromise(retVal)) { | ||
const invalidMiddlewareReturnError = new Error('Unexpected return value in onError middleware') | ||
// embed original error to avoid swallowing the real exception | ||
invalidMiddlewareReturnError.originalError = err | ||
throw invalidMiddlewareReturnError | ||
} | ||
retVal | ||
.then(runNext) | ||
.catch(done) | ||
} | ||
return | ||
} | ||
@@ -87,0 +116,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
321296
34
8475
536
14