idea-aws 4.3.3 → 4.3.5

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.
@@ -14,13 +14,17 @@ export declare abstract class GenericController {
14
14
  */
15
15
  constructor(event: any, callback: any);
16
16
  /**
17
- * The main function, that handle the request and should terminate with an invokation of the method `done`.
17
+ * The main function (to override), that handles the request and must terminate invoking the method `done`.
18
18
  */
19
- abstract handleRequest(): void;
19
+ handleRequest(): Promise<void>;
20
20
  /**
21
21
  * Default callback for the Lambda.
22
22
  */
23
- protected done(error: Error | any, res?: any): void;
23
+ protected done(error?: Error | any, res?: any): void;
24
+ /**
25
+ * Remap an error to manage the logging and make sure no unhandled error is returned to the requester.
26
+ */
27
+ protected handleControllerError(err: Error | HandledError | any, interceptedInContext: string, replaceWithMessage: string): HandledError | UnhandledError;
24
28
  /**
25
29
  * Get the current log level for the current Lambda function's `logger`.
26
30
  * Note: "FATAL" means that no log will be printed.
@@ -35,3 +39,22 @@ export declare abstract class GenericController {
35
39
  */
36
40
  silentLambdaLogs(): void;
37
41
  }
42
+ /**
43
+ * A specific type of error in the context of the Controller, to distinguish from "unhandled" errors.
44
+ */
45
+ export declare class HandledError extends Error {
46
+ constructor(message: string);
47
+ }
48
+ /**
49
+ * An unhandled error thrown inside the controller (i.e. `!(error instanceof HandledError)`) .
50
+ */
51
+ export declare class UnhandledError extends Error {
52
+ /**
53
+ * The context where the unhandled error was intercepted.
54
+ */
55
+ unhandled: string;
56
+ /**
57
+ * The original error message before it was replaced by a public-facing message.
58
+ */
59
+ internalMessage: string;
60
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GenericController = void 0;
3
+ exports.UnhandledError = exports.HandledError = exports.GenericController = void 0;
4
4
  require("source-map-support/register");
5
5
  const lambdaLogger_1 = require("./lambdaLogger");
6
6
  /**
@@ -17,16 +17,39 @@ class GenericController {
17
17
  this.event = event;
18
18
  this.callback = callback;
19
19
  }
20
+ /**
21
+ * The main function (to override), that handles the request and must terminate invoking the method `done`.
22
+ */
23
+ async handleRequest() {
24
+ this.logger.info('START');
25
+ this.done();
26
+ }
20
27
  /**
21
28
  * Default callback for the Lambda.
22
29
  */
23
- done(error, res) {
24
- if (error)
25
- this.logger.error('END-FAILED', error);
30
+ done(error = null, res) {
31
+ if (error) {
32
+ if (error.unhandled)
33
+ this.logger.error('END-FAILED', error);
34
+ else
35
+ this.logger.warn('END-FAILED', error);
36
+ }
26
37
  else
27
38
  this.logger.info('END-SUCCESS');
28
39
  this.callback(error, res);
29
40
  }
41
+ /**
42
+ * Remap an error to manage the logging and make sure no unhandled error is returned to the requester.
43
+ */
44
+ handleControllerError(err, interceptedInContext, replaceWithMessage) {
45
+ if (err instanceof HandledError)
46
+ return err;
47
+ const error = err;
48
+ error.unhandled = interceptedInContext;
49
+ error.internalMessage = error.message;
50
+ error.message = replaceWithMessage;
51
+ return error;
52
+ }
30
53
  /**
31
54
  * Get the current log level for the current Lambda function's `logger`.
32
55
  * Note: "FATAL" means that no log will be printed.
@@ -48,3 +71,19 @@ class GenericController {
48
71
  }
49
72
  }
50
73
  exports.GenericController = GenericController;
74
+ /**
75
+ * A specific type of error in the context of the Controller, to distinguish from "unhandled" errors.
76
+ */
77
+ class HandledError extends Error {
78
+ constructor(message) {
79
+ super(message);
80
+ Object.setPrototypeOf(this, HandledError.prototype);
81
+ }
82
+ }
83
+ exports.HandledError = HandledError;
84
+ /**
85
+ * An unhandled error thrown inside the controller (i.e. `!(error instanceof HandledError)`) .
86
+ */
87
+ class UnhandledError extends Error {
88
+ }
89
+ exports.UnhandledError = UnhandledError;
@@ -43,7 +43,6 @@ export declare abstract class ResourceController extends GenericController {
43
43
  */
44
44
  protected getQueryParamAsArray(paramName: string): string[];
45
45
  handleRequest: () => Promise<void>;
46
- private remapHandlerError;
47
46
  protected done(error?: Error | any, rawResult?: any, statusCode?: number): void;
48
47
  /**
49
48
  * To @override
@@ -225,9 +224,3 @@ export interface InternalAPIRequestParams {
225
224
  */
226
225
  body?: any;
227
226
  }
228
- /**
229
- * Explicitly define a specific type of error to use in the RC's handler, to distinguish it from the normal errors.
230
- */
231
- export declare class RCError extends Error {
232
- constructor(message: string);
233
- }
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.RCError = exports.ResourceController = void 0;
26
+ exports.ResourceController = void 0;
27
27
  const fs_1 = require("fs");
28
28
  const Lambda = __importStar(require("@aws-sdk/client-lambda"));
29
29
  const EventBridge = __importStar(require("@aws-sdk/client-eventbridge"));
@@ -49,6 +49,7 @@ class ResourceController extends genericController_1.GenericController {
49
49
  /// REQUEST HANDLERS
50
50
  ///
51
51
  this.handleRequest = async () => {
52
+ this.logger.info('START', { event: this.getEventSummary() });
52
53
  if (this.initError)
53
54
  return;
54
55
  try {
@@ -77,7 +78,7 @@ class ResourceController extends genericController_1.GenericController {
77
78
  response = await this.headResource();
78
79
  break;
79
80
  default:
80
- this.done(new RCError('Unsupported method'));
81
+ this.done(new genericController_1.HandledError('Unsupported method'));
81
82
  }
82
83
  }
83
84
  else {
@@ -102,17 +103,17 @@ class ResourceController extends genericController_1.GenericController {
102
103
  response = await this.headResources();
103
104
  break;
104
105
  default:
105
- this.done(new RCError('Unsupported method'));
106
+ this.done(new genericController_1.HandledError('Unsupported method'));
106
107
  }
107
108
  }
108
109
  this.done(null, response);
109
110
  }
110
111
  catch (err) {
111
- this.done(this.remapHandlerError(err, 'HANDLER-ERROR', 'Operation failed'));
112
+ this.done(this.handleControllerError(err, 'HANDLER-ERROR', 'Operation failed'));
112
113
  }
113
114
  }
114
115
  catch (err) {
115
- this.done(this.remapHandlerError(err, 'AUTH-CHECK-ERROR', 'Forbidden'));
116
+ this.done(this.handleControllerError(err, 'AUTH-CHECK-ERROR', 'Forbidden'));
116
117
  }
117
118
  };
118
119
  this.event = event;
@@ -138,11 +139,10 @@ class ResourceController extends genericController_1.GenericController {
138
139
  }
139
140
  if (options.useMetrics)
140
141
  this.prepareMetrics();
141
- this.logger.info('START', { event: this.getEventSummary() });
142
142
  }
143
143
  catch (err) {
144
144
  this.initError = true;
145
- this.done(this.remapHandlerError(err, 'INIT-ERROR', 'Malformed request'));
145
+ this.done(this.handleControllerError(err, 'INIT-ERROR', 'Malformed request'));
146
146
  }
147
147
  }
148
148
  initFromEventV2(event, options) {
@@ -165,7 +165,7 @@ class ResourceController extends genericController_1.GenericController {
165
165
  this.body = (event.body ? JSON.parse(event.body) : {}) || {};
166
166
  }
167
167
  catch (error) {
168
- throw new RCError('Malformed body');
168
+ throw new genericController_1.HandledError('Malformed body');
169
169
  }
170
170
  }
171
171
  initFromEventV1(event, options) {
@@ -187,7 +187,7 @@ class ResourceController extends genericController_1.GenericController {
187
187
  this.body = (event.body ? JSON.parse(event.body) : {}) || {};
188
188
  }
189
189
  catch (error) {
190
- throw new RCError('Malformed body');
190
+ throw new genericController_1.HandledError('Malformed body');
191
191
  }
192
192
  }
193
193
  getEventSummary() {
@@ -213,17 +213,9 @@ class ResourceController extends genericController_1.GenericController {
213
213
  else
214
214
  return String(this.queryParams[paramName]).split(',');
215
215
  }
216
- remapHandlerError(err, interceptedInContext, replaceWithMessage) {
217
- if (err instanceof RCError)
218
- return err;
219
- const error = err;
220
- error.unhandled = interceptedInContext;
221
- error.internalMessage = error.message;
222
- error.message = replaceWithMessage;
223
- return error;
224
- }
225
216
  done(error, rawResult, statusCode = this.returnStatusCode ?? (error ? 400 : 200)) {
226
217
  const result = error ? { message: error.message } : rawResult ?? {};
218
+ this.logger.debug('END-DETAIL', { result: Array.isArray(result) ? { array: result.length } : result });
227
219
  const finalLogContent = { statusCode, event: this.getEventSummary() };
228
220
  if (error) {
229
221
  if (error.unhandled)
@@ -233,7 +225,6 @@ class ResourceController extends genericController_1.GenericController {
233
225
  }
234
226
  else
235
227
  this.logger.info('END-SUCCESS', finalLogContent);
236
- this.logger.debug('END-DETAIL', { result: Array.isArray(result) ? { array: result.length } : result });
237
228
  if (this.logRequestsWithKey)
238
229
  this.storeLog(!error);
239
230
  if (this.metrics)
@@ -254,73 +245,73 @@ class ResourceController extends genericController_1.GenericController {
254
245
  * To @override
255
246
  */
256
247
  async getResource() {
257
- throw new RCError('Unsupported method');
248
+ throw new genericController_1.HandledError('Unsupported method');
258
249
  }
259
250
  /**
260
251
  * To @override
261
252
  */
262
253
  async postResource() {
263
- throw new RCError('Unsupported method');
254
+ throw new genericController_1.HandledError('Unsupported method');
264
255
  }
265
256
  /**
266
257
  * To @override
267
258
  */
268
259
  async putResource() {
269
- throw new RCError('Unsupported method');
260
+ throw new genericController_1.HandledError('Unsupported method');
270
261
  }
271
262
  /**
272
263
  * To @override
273
264
  */
274
265
  async deleteResource() {
275
- throw new RCError('Unsupported method');
266
+ throw new genericController_1.HandledError('Unsupported method');
276
267
  }
277
268
  /**
278
269
  * To @override
279
270
  */
280
271
  async headResource() {
281
- throw new RCError('Unsupported method');
272
+ throw new genericController_1.HandledError('Unsupported method');
282
273
  }
283
274
  /**
284
275
  * To @override
285
276
  */
286
277
  async getResources() {
287
- throw new RCError('Unsupported method');
278
+ throw new genericController_1.HandledError('Unsupported method');
288
279
  }
289
280
  /**
290
281
  * To @override
291
282
  */
292
283
  async postResources() {
293
- throw new RCError('Unsupported method');
284
+ throw new genericController_1.HandledError('Unsupported method');
294
285
  }
295
286
  /**
296
287
  * To @override
297
288
  */
298
289
  async putResources() {
299
- throw new RCError('Unsupported method');
290
+ throw new genericController_1.HandledError('Unsupported method');
300
291
  }
301
292
  /**
302
293
  * To @override
303
294
  */
304
295
  async patchResource() {
305
- throw new RCError('Unsupported method');
296
+ throw new genericController_1.HandledError('Unsupported method');
306
297
  }
307
298
  /**
308
299
  * To @override
309
300
  */
310
301
  async patchResources() {
311
- throw new RCError('Unsupported method');
302
+ throw new genericController_1.HandledError('Unsupported method');
312
303
  }
313
304
  /**
314
305
  * To @override
315
306
  */
316
307
  async deleteResources() {
317
- throw new RCError('Unsupported method');
308
+ throw new genericController_1.HandledError('Unsupported method');
318
309
  }
319
310
  /**
320
311
  * To @override
321
312
  */
322
313
  async headResources() {
323
- throw new RCError('Unsupported method');
314
+ throw new genericController_1.HandledError('Unsupported method');
324
315
  }
325
316
  ///
326
317
  /// HELPERS
@@ -542,18 +533,3 @@ class ResourceController extends genericController_1.GenericController {
542
533
  }
543
534
  }
544
535
  exports.ResourceController = ResourceController;
545
- /**
546
- * Explicitly define a specific type of error to use in the RC's handler, to distinguish it from the normal errors.
547
- */
548
- class RCError extends Error {
549
- constructor(message) {
550
- super(message);
551
- Object.setPrototypeOf(this, RCError.prototype);
552
- }
553
- }
554
- exports.RCError = RCError;
555
- /**
556
- * An unhandled error thrown inside the RC (i.e. `!(error instanceof RCError)`) .
557
- */
558
- class RCUnhandledError extends Error {
559
- }
@@ -1,3 +1,4 @@
1
+ import { DynamoDBRecord } from 'aws-lambda';
1
2
  import { GenericController } from './genericController';
2
3
  /**
3
4
  * An abstract class to inherit to manage AWS DDB streams in an AWS Lambda function.
@@ -5,4 +6,6 @@ import { GenericController } from './genericController';
5
6
  export declare abstract class StreamController extends GenericController {
6
7
  records: any[];
7
8
  constructor(event: any, callback: any);
9
+ protected abstract handleRecord(record: DynamoDBRecord): Promise<void>;
10
+ handleRequest(): Promise<void>;
8
11
  }
@@ -9,7 +9,12 @@ class StreamController extends genericController_1.GenericController {
9
9
  constructor(event, callback) {
10
10
  super(event, callback);
11
11
  this.records = event.Records ?? [];
12
- this.logger.info('START STREAM', { records: this.records.length ?? 0 });
12
+ }
13
+ async handleRequest() {
14
+ this.logger.info('START', { streamOfRecords: this.records.length ?? 0 });
15
+ await Promise.all(this.records.map(record => this.handleRecord(record)))
16
+ .then(() => this.done())
17
+ .catch((err) => this.done(this.handleControllerError(err, 'STREAM-ERROR', 'Operation failed')));
13
18
  }
14
19
  }
15
20
  exports.StreamController = StreamController;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "idea-aws",
3
- "version": "4.3.3",
3
+ "version": "4.3.5",
4
4
  "description": "AWS wrappers to use in IDEA's back-ends",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -38,7 +38,7 @@
38
38
  "homepage": "https://iter-idea.github.io/IDEA-AWS",
39
39
  "dependencies": {
40
40
  "@aws-lambda-powertools/metrics": "^1.17.0",
41
- "idea-toolbox": "^7.0.1",
41
+ "idea-toolbox": "^7.0.2",
42
42
  "nanoid": "^3.3.7",
43
43
  "nodemailer": "^6.9.8",
44
44
  "source-map-support": "^0.5.21"