From 4e035041b228098e29cb4ac9883a6f11d425dd4b Mon Sep 17 00:00:00 2001 From: Jason Barto Date: Sat, 8 Feb 2020 20:42:04 +0000 Subject: [PATCH 1/5] added a flag to catch thrown exceptions, the default is to NOT catch it which is the original library behavior --- lib/failure.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/failure.js b/lib/failure.js index 2fdfc8c..17e645d 100644 --- a/lib/failure.js +++ b/lib/failure.js @@ -3,7 +3,7 @@ const aws = require('aws-sdk') const ssm = new aws.SSM() const childProcess = require('child_process') -async function getConfig () { +async function getConfig() { try { let params = { Name: process.env.FAILURE_INJECTION_PARAM @@ -17,10 +17,13 @@ async function getConfig () { } var injectFailure = function (fn) { return async function () { + var catchFlag = false + try { let configResponse = await getConfig() let config = JSON.parse(configResponse) if (config.isEnabled === true && Math.random() < config.rate) { + catchFlag = config.catchException if (config.failureMode === 'latency') { let latencyRange = config.maxLatency - config.minLatency let setLatency = Math.floor(config.minLatency + Math.random() * latencyRange) @@ -41,8 +44,10 @@ var injectFailure = function (fn) { return fn.apply(this, arguments) } catch (ex) { console.log(ex) + if (catchFlag) { + throw ex + } } } -} -module.exports = injectFailure + module.exports = injectFailure From 575dce08cae868424d4b0404410993ed0dbb4bda Mon Sep 17 00:00:00 2001 From: Jason Barto Date: Sat, 8 Feb 2020 20:49:43 +0000 Subject: [PATCH 2/5] fixed small syntax issue with braces --- lib/failure.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/failure.js b/lib/failure.js index 17e645d..6c8f163 100644 --- a/lib/failure.js +++ b/lib/failure.js @@ -49,5 +49,5 @@ var injectFailure = function (fn) { } } } - - module.exports = injectFailure +} +module.exports = injectFailure From aa7c14321c355ea10cef3a2463dac578ff3f8fb5 Mon Sep 17 00:00:00 2001 From: Jason Barto Date: Sat, 8 Feb 2020 20:53:14 +0000 Subject: [PATCH 3/5] clarified a boolean logic error --- lib/failure.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/failure.js b/lib/failure.js index 6c8f163..a9795df 100644 --- a/lib/failure.js +++ b/lib/failure.js @@ -17,7 +17,7 @@ async function getConfig() { } var injectFailure = function (fn) { return async function () { - var catchFlag = false + var catchFlag = true try { let configResponse = await getConfig() @@ -44,7 +44,7 @@ var injectFailure = function (fn) { return fn.apply(this, arguments) } catch (ex) { console.log(ex) - if (catchFlag) { + if (! catchFlag) { throw ex } } From e55933ea936ca16febe6bed9a00aadb8d420b8ea Mon Sep 17 00:00:00 2001 From: Jason Barto Date: Sat, 8 Feb 2020 20:59:54 +0000 Subject: [PATCH 4/5] added documentation to the README --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 362b8da..5bed576 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ exports.handler = failureLambda(async (event, context) => { ``` 4. Create a parameter in SSM Parameter Store. ```json -{"isEnabled": false, "failureMode": "latency", "rate": 1, "minLatency": 100, "maxLatency": 400, "exceptionMsg": "Exception message!", "statusCode": 404, "diskSpace": 100} +{"isEnabled": false, "failureMode": "latency", "rate": 1, "catchException": false, "minLatency": 100, "maxLatency": 400, "exceptionMsg": "Exception message!", "statusCode": 404, "diskSpace": 100} ``` ```bash aws ssm put-parameter --region eu-north-1 --name failureLambdaConfig --type String --overwrite --value "{\"isEnabled\": false, \"failureMode\": \"latency\", \"rate\": 1, \"minLatency\": 100, \"maxLatency\": 400, \"exceptionMsg\": \"Exception message!\", \"statusCode\": 404, \"diskSpace\": 100}" @@ -38,6 +38,7 @@ Edit the values of your parameter in SSM Parameter Store to use the failure inje * `isEnabled: false` means that the failure injection module is disabled and no failure is injected. * `failureMode` selects which failure you want to inject. The options are `latency`, `exception` or `statuscode` as explained below. * `rate` controls the rate of failure. 1 means that failure is injected on all invocations and 0.5 that failure is injected on about half of all invocations. +* `catchException` specifies whether to catch any thrown exceptions or to pass them through to Lambda (**default** is false) * `minLatency` and `maxLatency` is the span of latency in milliseconds injected into your function when `failureMode` is set to `latency`. * `exceptionMsg` is the message thrown with the exception created when `failureMode` is set to `exception`. * `statusCode` is the status code returned by your function when `failureMode` is set to `statuscode`. @@ -57,6 +58,10 @@ Inspired by Yan Cui's articles on latency injection for AWS Lambda (https://hack ## Changelog +### 2020-02-08 v0.1.1 + +* Added a flag to determine whether to catch or release errors before they reach AWS Lambda + ### 2019-12-30 v0.1.0 * Added disk space failure. @@ -68,4 +73,4 @@ Inspired by Yan Cui's articles on latency injection for AWS Lambda (https://hack ## Authors -**Gunnar Grosch** - [GitHub](https://github.com/gunnargrosch) | [Twitter](https://twitter.com/gunnargrosch) | [LinkedIn](https://www.linkedin.com/in/gunnargrosch/) \ No newline at end of file +**Gunnar Grosch** - [GitHub](https://github.com/gunnargrosch) | [Twitter](https://twitter.com/gunnargrosch) | [LinkedIn](https://www.linkedin.com/in/gunnargrosch/) From 17d85b0f0eb3defdb6d2c57b60f577709f8115f7 Mon Sep 17 00:00:00 2001 From: Gunnar Grosch Date: Thu, 13 Feb 2020 11:52:16 +0100 Subject: [PATCH 5/5] Modified to only include the exception fix for now --- README.md | 7 +++---- lib/failure.js | 8 ++------ package.json | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 5bed576..27b257f 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ exports.handler = failureLambda(async (event, context) => { ``` 4. Create a parameter in SSM Parameter Store. ```json -{"isEnabled": false, "failureMode": "latency", "rate": 1, "catchException": false, "minLatency": 100, "maxLatency": 400, "exceptionMsg": "Exception message!", "statusCode": 404, "diskSpace": 100} +{"isEnabled": false, "failureMode": "latency", "rate": 1, "minLatency": 100, "maxLatency": 400, "exceptionMsg": "Exception message!", "statusCode": 404, "diskSpace": 100} ``` ```bash aws ssm put-parameter --region eu-north-1 --name failureLambdaConfig --type String --overwrite --value "{\"isEnabled\": false, \"failureMode\": \"latency\", \"rate\": 1, \"minLatency\": 100, \"maxLatency\": 400, \"exceptionMsg\": \"Exception message!\", \"statusCode\": 404, \"diskSpace\": 100}" @@ -38,7 +38,6 @@ Edit the values of your parameter in SSM Parameter Store to use the failure inje * `isEnabled: false` means that the failure injection module is disabled and no failure is injected. * `failureMode` selects which failure you want to inject. The options are `latency`, `exception` or `statuscode` as explained below. * `rate` controls the rate of failure. 1 means that failure is injected on all invocations and 0.5 that failure is injected on about half of all invocations. -* `catchException` specifies whether to catch any thrown exceptions or to pass them through to Lambda (**default** is false) * `minLatency` and `maxLatency` is the span of latency in milliseconds injected into your function when `failureMode` is set to `latency`. * `exceptionMsg` is the message thrown with the exception created when `failureMode` is set to `exception`. * `statusCode` is the status code returned by your function when `failureMode` is set to `statuscode`. @@ -58,9 +57,9 @@ Inspired by Yan Cui's articles on latency injection for AWS Lambda (https://hack ## Changelog -### 2020-02-08 v0.1.1 +### 2020-02-13 v0.1.1 -* Added a flag to determine whether to catch or release errors before they reach AWS Lambda +* Fixed issue with exception injection not throwing the exception. Thanks to [Jason Barto](https://github.com/jpbarto)! ### 2019-12-30 v0.1.0 diff --git a/lib/failure.js b/lib/failure.js index a9795df..8902d6a 100644 --- a/lib/failure.js +++ b/lib/failure.js @@ -17,13 +17,10 @@ async function getConfig() { } var injectFailure = function (fn) { return async function () { - var catchFlag = true - try { let configResponse = await getConfig() let config = JSON.parse(configResponse) if (config.isEnabled === true && Math.random() < config.rate) { - catchFlag = config.catchException if (config.failureMode === 'latency') { let latencyRange = config.maxLatency - config.minLatency let setLatency = Math.floor(config.minLatency + Math.random() * latencyRange) @@ -44,10 +41,9 @@ var injectFailure = function (fn) { return fn.apply(this, arguments) } catch (ex) { console.log(ex) - if (! catchFlag) { - throw ex - } + throw ex } } } + module.exports = injectFailure diff --git a/package.json b/package.json index a6ac9f8..fbb467d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "failure-lambda", - "version": "0.1.0", + "version": "0.1.1", "description": "Module for failure injection into AWS Lambda", "main": "./lib/failure.js", "scripts": {