@comicrelief/lambda-wrapper 1.8.1 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Lambda Wrapper
2
2
 
3
- [![CircleCI](https://circleci.com/gh/comicrelief/lambda-wrapper.svg?style=svg&circle-token=7db6e0ff0526bd635424f303fd4ffffc7ea05aed)](https://circleci.com/gh/comicrelief/lambda-wrapper)
3
+ ![GitHub Actions](https://github.com/comicrelief/lambda-wrapper/actions/workflows/main.yml/badge.svg)
4
4
  [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
5
5
  [![semantic-release](https://badge.fury.io/js/%40comicrelief%2Flambda-wrapper.svg)](https://www.npmjs.com/package/@comicrelief/lambda-wrapper)
6
6
 
@@ -85,7 +85,12 @@ By default, messages will be sent to a SQS service running on `localhost:4576`.
85
85
 
86
86
  ### AWS SQS mode
87
87
 
88
- Use this mode by setting `LAMBDA_WRAPPER_OFFLINE_SQS_MODE=aws`. Messages will be sent to the real queue in AWS. This is useful for running end-to-end tests where a message is sent to a queue and eventually appears in an external data store.
88
+ Use this mode by setting `LAMBDA_WRAPPER_OFFLINE_SQS_MODE=aws`. Messages will be sent to the real queue in AWS. This mode is useful when a queue is consumed by an external service, rather than another function in the service under test.
89
+
90
+ In order for queue URLs to be correctly constructed, you must either:
91
+
92
+ - set `AWS_ACCOUNT_ID` to the account ID that hosts your queue; or
93
+ - invoke offline functions via the Lambda API, passing a context that contains a realistic `invokedFunctionArn` including the account ID.
89
94
 
90
95
  ## Semantic release
91
96
 
@@ -245,7 +245,7 @@ class LoggerService extends _DependencyAware.default {
245
245
 
246
246
  label(descriptor, silent = false) {
247
247
  if (typeof process.env.EPSAGON_TOKEN === 'string' && process.env.EPSAGON_TOKEN !== 'undefined' && typeof process.env.EPSAGON_SERVICE_NAME === 'string' && process.env.EPSAGON_SERVICE_NAME !== 'undefined') {
248
- _epsagon.default.label(descriptor);
248
+ _epsagon.default.label(descriptor, true);
249
249
  }
250
250
 
251
251
  if (silent === false) {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.default = exports.SQS_PUBLISH_FAILURE_MODES = exports.SQS_OFFLINE_MODES = void 0;
7
7
 
8
8
  var _alai = _interopRequireDefault(require("alai"));
9
9
 
@@ -32,7 +32,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
32
32
  /**
33
33
  * Allowed values for `process.env.LAMBDA_WRAPPER_OFFLINE_SQS_MODE`.
34
34
  */
35
- const OFFLINE_MODES = {
35
+ const SQS_OFFLINE_MODES = {
36
36
  /**
37
37
  * When running offline, messages will trigger the consumer function directly
38
38
  * via a Lambda endpoint, set using `process.env.SERVICE_LAMBDA_URL`. This is
@@ -51,10 +51,34 @@ const OFFLINE_MODES = {
51
51
  */
52
52
  AWS: 'aws'
53
53
  };
54
+ /**
55
+ * Defines the preferred behaviour
56
+ * for SQSService.prototype.publish
57
+ * should AWS SQS fail.
58
+ */
59
+
60
+ exports.SQS_OFFLINE_MODES = SQS_OFFLINE_MODES;
61
+ const SQS_PUBLISH_FAILURE_MODES = {
62
+ /**
63
+ * Catches the exception and logs it.
64
+ * This is the default behaviour
65
+ * for LambdaWrapper 1.8.0 and below
66
+ * and for LambdaWrapper 1.8.2 and above
67
+ */
68
+ CATCH: 'catch',
69
+
70
+ /**
71
+ * Throws the exception so that the caller
72
+ * can handle it directly.
73
+ */
74
+ THROW: 'throw'
75
+ };
54
76
  /**
55
77
  * SQSService class
56
78
  */
57
79
 
80
+ exports.SQS_PUBLISH_FAILURE_MODES = SQS_PUBLISH_FAILURE_MODES;
81
+
58
82
  class SQSService extends _DependencyAware.default {
59
83
  /**
60
84
  * SQSService constructor
@@ -63,31 +87,33 @@ class SQSService extends _DependencyAware.default {
63
87
  */
64
88
  constructor(di) {
65
89
  super(di);
90
+ const {
91
+ LAMBDA_WRAPPER_OFFLINE_SQS_HOST: offlineHost = 'localhost',
92
+ LAMBDA_WRAPPER_OFFLINE_SQS_MODE: offlineMode = SQS_OFFLINE_MODES.DIRECT,
93
+ AWS_ACCOUNT_ID,
94
+ REGION
95
+ } = process.env;
66
96
  const container = this.getContainer();
67
97
  const context = container.getContext();
68
98
  const queues = container.getConfiguration('QUEUES');
99
+ const accountId = context && context.invokedFunctionArn && _alai.default.parse(context) || AWS_ACCOUNT_ID;
69
100
  this.queues = {};
70
101
  this.$lambda = null;
71
102
  this.$sqs = null;
72
- const {
73
- LAMBDA_WRAPPER_OFFLINE_SQS_HOST: offlineHost = 'localhost',
74
- LAMBDA_WRAPPER_OFFLINE_SQS_MODE: offlineMode = OFFLINE_MODES.DIRECT,
75
- REGION
76
- } = process.env;
77
103
 
78
- if (container.isOffline && !Object.values(OFFLINE_MODES).includes(offlineMode)) {
79
- throw new Error(`Invalid LAMBDA_WRAPPER_OFFLINE_SQS_MODE: ${offlineMode}\n` + `Please use one of: ${Object.values(OFFLINE_MODES).join(', ')}`);
104
+ if (container.isOffline && !Object.values(SQS_OFFLINE_MODES).includes(offlineMode)) {
105
+ throw new Error(`Invalid LAMBDA_WRAPPER_OFFLINE_SQS_MODE: ${offlineMode}\n` + `Please use one of: ${Object.values(SQS_OFFLINE_MODES).join(', ')}`);
80
106
  } // Add the queues from configuration
81
107
 
82
108
 
83
109
  if (queues !== null && Object.keys(queues).length > 0) {
84
110
  Object.keys(queues).forEach(queueDefinition => {
85
- if (container.isOffline && offlineMode === OFFLINE_MODES.LOCAL) {
111
+ if (container.isOffline && offlineMode === SQS_OFFLINE_MODES.LOCAL) {
86
112
  // custom URL when using an offline SQS service such as Localstack
87
113
  this.queues[queueDefinition] = `http://${offlineHost}:4576/queue/${queues[queueDefinition]}`;
88
114
  } else {
89
115
  // default AWS queue URL
90
- this.queues[queueDefinition] = `https://sqs.${REGION}.amazonaws.com/${_alai.default.parse(context)}/${queues[queueDefinition]}`;
116
+ this.queues[queueDefinition] = `https://sqs.${REGION}.amazonaws.com/${accountId}/${queues[queueDefinition]}`;
91
117
  }
92
118
  });
93
119
  }
@@ -139,12 +165,12 @@ class SQSService extends _DependencyAware.default {
139
165
  * Returns the mode to use for offline SQS.
140
166
  *
141
167
  * This is configured by `process.env.LAMBDA_WRAPPER_OFFLINE_SQS_MODE`. The
142
- * default is `OFFLINE_MODES.LAMBDA`.
168
+ * default is `SQS_OFFLINE_MODES.LAMBDA`.
143
169
  */
144
170
 
145
171
 
146
172
  static get offlineMode() {
147
- return process.env.LAMBDA_WRAPPER_OFFLINE_SQS_MODE || OFFLINE_MODES.DIRECT;
173
+ return process.env.LAMBDA_WRAPPER_OFFLINE_SQS_MODE || SQS_OFFLINE_MODES.DIRECT;
148
174
  }
149
175
  /**
150
176
  * Batch delete messages
@@ -267,11 +293,18 @@ class SQSService extends _DependencyAware.default {
267
293
  * @param queue string
268
294
  * @param messageObject object
269
295
  * @param messageGroupId string
296
+ * @param {'catch' | 'throw'} failureMode Choose how failures are handled:
297
+ * - `catch`: errors will be caught and logged. This is the default.
298
+ * - `throw`: errors will be thrown, causing promise to reject.
270
299
  * @returns {Promise<any>}
271
300
  */
272
301
 
273
302
 
274
- async publish(queue, messageObject, messageGroupId = null) {
303
+ async publish(queue, messageObject, messageGroupId = null, failureMode = SQS_PUBLISH_FAILURE_MODES.CATCH) {
304
+ if (!Object.values(SQS_PUBLISH_FAILURE_MODES).includes(failureMode)) {
305
+ throw new Error(`Invalid value for 'failureMode': ${failureMode}`);
306
+ }
307
+
275
308
  const container = this.getContainer();
276
309
  const queueUrl = this.queues[queue];
277
310
  const Timer = container.get(_Dependencies.DEFINITIONS.TIMER);
@@ -287,10 +320,22 @@ class SQSService extends _DependencyAware.default {
287
320
  messageParameters.MessageGroupId = messageGroupId !== null ? messageGroupId : (0, _uuid.v4)();
288
321
  }
289
322
 
290
- if (container.isOffline && this.constructor.offlineMode === OFFLINE_MODES.DIRECT) {
291
- await this.publishOffline(queue, messageParameters);
292
- } else {
293
- await this.sqs.sendMessage(messageParameters).promise();
323
+ try {
324
+ if (container.isOffline && this.constructor.offlineMode === SQS_OFFLINE_MODES.DIRECT) {
325
+ await this.publishOffline(queue, messageParameters);
326
+ } else {
327
+ await this.sqs.sendMessage(messageParameters).promise();
328
+ }
329
+ } catch (error) {
330
+ switch (failureMode) {
331
+ case SQS_PUBLISH_FAILURE_MODES.CATCH:
332
+ container.get(_Dependencies.DEFINITIONS.LOGGER).error(error);
333
+ return null;
334
+
335
+ case SQS_PUBLISH_FAILURE_MODES.THROW:
336
+ default:
337
+ throw error;
338
+ }
294
339
  }
295
340
 
296
341
  return queue;
@@ -24,8 +24,9 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
24
24
  * @param outcome
25
25
  */
26
26
  const handleSuccess = (di, outcome) => {
27
- const logger = di.get(_Dependencies.DEFINITIONS.LOGGER);
28
- logger.metric('lambda.statusCode', outcome.statusCode || 200);
27
+ const logger = di.get(_Dependencies.DEFINITIONS.LOGGER); // Outcome may be undefined as not all lambdas have a return value.
28
+
29
+ logger.metric('lambda.statusCode', outcome && outcome.statusCode || 200);
29
30
  return outcome;
30
31
  };
31
32
  /**
package/dist/index.js CHANGED
@@ -93,6 +93,18 @@ Object.defineProperty(exports, "SQSService", {
93
93
  return _SQS.default;
94
94
  }
95
95
  });
96
+ Object.defineProperty(exports, "SQS_OFFLINE_MODES", {
97
+ enumerable: true,
98
+ get: function () {
99
+ return _SQS.SQS_OFFLINE_MODES;
100
+ }
101
+ });
102
+ Object.defineProperty(exports, "SQS_PUBLISH_FAILURE_MODES", {
103
+ enumerable: true,
104
+ get: function () {
105
+ return _SQS.SQS_PUBLISH_FAILURE_MODES;
106
+ }
107
+ });
96
108
  Object.defineProperty(exports, "LambdaTermination", {
97
109
  enumerable: true,
98
110
  get: function () {
@@ -136,7 +148,7 @@ var _Logger = _interopRequireDefault(require("./Service/Logger.service"));
136
148
 
137
149
  var _Request = _interopRequireDefault(require("./Service/Request.service"));
138
150
 
139
- var _SQS = _interopRequireDefault(require("./Service/SQS.service"));
151
+ var _SQS = _interopRequireWildcard(require("./Service/SQS.service"));
140
152
 
141
153
  var _LambdaTermination = _interopRequireDefault(require("./Wrapper/LambdaTermination"));
142
154
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comicrelief/lambda-wrapper",
3
- "version": "1.8.1",
3
+ "version": "1.9.1",
4
4
  "description": "Lambda wrapper for all Comic Relief Serverless Projects",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {