sqs-consumer 6.1.0 → 6.2.0

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/dist/consumer.js CHANGED
@@ -3,74 +3,29 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Consumer = void 0;
4
4
  const client_sqs_1 = require("@aws-sdk/client-sqs");
5
5
  const debug_1 = require("debug");
6
- const events_1 = require("events");
6
+ const types_1 = require("./types");
7
7
  const bind_1 = require("./bind");
8
8
  const errors_1 = require("./errors");
9
+ const validation_1 = require("./validation");
9
10
  const debug = (0, debug_1.default)('sqs-consumer');
10
- const requiredOptions = [
11
- 'queueUrl',
12
- // only one of handleMessage / handleMessagesBatch is required
13
- 'handleMessage|handleMessageBatch'
14
- ];
15
- function createTimeout(duration) {
16
- let timeout;
17
- const pending = new Promise((_, reject) => {
18
- timeout = setTimeout(() => {
19
- reject(new errors_1.TimeoutError());
20
- }, duration);
21
- });
22
- return [timeout, pending];
23
- }
24
- function assertOptions(options) {
25
- requiredOptions.forEach((option) => {
26
- const possibilities = option.split('|');
27
- if (!possibilities.find((p) => options[p])) {
28
- throw new Error(`Missing SQS consumer option [ ${possibilities.join(' or ')} ].`);
29
- }
30
- });
31
- if (options.batchSize > 10 || options.batchSize < 1) {
32
- throw new Error('SQS batchSize option must be between 1 and 10.');
33
- }
34
- if (options.heartbeatInterval &&
35
- !(options.heartbeatInterval < options.visibilityTimeout)) {
36
- throw new Error('heartbeatInterval must be less than visibilityTimeout.');
37
- }
38
- }
39
- function isConnectionError(err) {
40
- if (err instanceof errors_1.SQSError) {
41
- return (err.statusCode === 403 ||
42
- err.code === 'CredentialsError' ||
43
- err.code === 'UnknownEndpoint' ||
44
- err.code === 'AWS.SimpleQueueService.NonExistentQueue');
45
- }
46
- return false;
47
- }
48
- function toSQSError(err, message) {
49
- var _a, _b;
50
- const sqsError = new errors_1.SQSError(message);
51
- sqsError.code = err.name;
52
- sqsError.statusCode = (_a = err.$metadata) === null || _a === void 0 ? void 0 : _a.httpStatusCode;
53
- sqsError.retryable = (_b = err.$retryable) === null || _b === void 0 ? void 0 : _b.throttling;
54
- sqsError.service = err.$service;
55
- sqsError.fault = err.$fault;
56
- sqsError.time = new Date();
57
- return sqsError;
58
- }
59
- function hasMessages(response) {
60
- return response.Messages && response.Messages.length > 0;
61
- }
62
- class Consumer extends events_1.EventEmitter {
11
+ /**
12
+ * [Usage](https://bbc.github.io/sqs-consumer/index.html#usage)
13
+ */
14
+ class Consumer extends types_1.TypedEventEmitter {
63
15
  constructor(options) {
64
16
  var _a, _b, _c, _d;
65
17
  super();
66
- assertOptions(options);
18
+ this.pollingTimeoutId = undefined;
19
+ this.heartbeatTimeoutId = undefined;
20
+ this.handleMessageTimeoutId = undefined;
21
+ this.stopped = true;
22
+ (0, validation_1.assertOptions)(options);
67
23
  this.queueUrl = options.queueUrl;
68
24
  this.handleMessage = options.handleMessage;
69
25
  this.handleMessageBatch = options.handleMessageBatch;
70
26
  this.handleMessageTimeout = options.handleMessageTimeout;
71
27
  this.attributeNames = options.attributeNames || [];
72
28
  this.messageAttributeNames = options.messageAttributeNames || [];
73
- this.stopped = true;
74
29
  this.batchSize = options.batchSize || 1;
75
30
  this.visibilityTimeout = options.visibilityTimeout;
76
31
  this.terminateVisibilityTimeout =
@@ -88,21 +43,15 @@ class Consumer extends events_1.EventEmitter {
88
43
  });
89
44
  (0, bind_1.autoBind)(this);
90
45
  }
91
- emit(event, ...args) {
92
- return super.emit(event, ...args);
93
- }
94
- on(event, listener) {
95
- return super.on(event, listener);
96
- }
97
- once(event, listener) {
98
- return super.once(event, listener);
99
- }
100
- get isRunning() {
101
- return !this.stopped;
102
- }
46
+ /**
47
+ * Creates a new SQS consumer.
48
+ */
103
49
  static create(options) {
104
50
  return new Consumer(options);
105
51
  }
52
+ /**
53
+ * Start polling the queue for messages.
54
+ */
106
55
  start() {
107
56
  if (this.stopped) {
108
57
  debug('Starting consumer');
@@ -110,117 +59,38 @@ class Consumer extends events_1.EventEmitter {
110
59
  this.poll();
111
60
  }
112
61
  }
62
+ /**
63
+ * Stop polling the queue for messages (pre existing requests will still be made until concluded).
64
+ */
113
65
  stop() {
114
- debug('Stopping consumer');
115
- this.stopped = true;
116
- }
117
- async handleSqsResponse(response) {
118
- debug('Received SQS response');
119
- debug(response);
120
- if (response) {
121
- if (hasMessages(response)) {
122
- if (this.handleMessageBatch) {
123
- // prefer handling messages in batch when available
124
- await this.processMessageBatch(response.Messages);
125
- }
126
- else {
127
- await Promise.all(response.Messages.map(this.processMessage));
128
- }
129
- this.emit('response_processed');
130
- }
131
- else {
132
- this.emit('empty');
133
- }
134
- }
135
- }
136
- async processMessage(message) {
137
- this.emit('message_received', message);
138
- let heartbeat;
139
- try {
140
- if (this.heartbeatInterval) {
141
- heartbeat = this.startHeartbeat(async () => {
142
- return this.changeVisibilityTimeout(message, this.visibilityTimeout);
143
- });
144
- }
145
- await this.executeHandler(message);
146
- await this.deleteMessage(message);
147
- this.emit('message_processed', message);
148
- }
149
- catch (err) {
150
- this.emitError(err, message);
151
- if (this.terminateVisibilityTimeout) {
152
- await this.changeVisibilityTimeout(message, 0);
153
- }
154
- }
155
- finally {
156
- clearInterval(heartbeat);
157
- }
158
- }
159
- async receiveMessage(params) {
160
- try {
161
- return await this.sqs.send(new client_sqs_1.ReceiveMessageCommand(params));
162
- }
163
- catch (err) {
164
- throw toSQSError(err, `SQS receive message failed: ${err.message}`);
165
- }
166
- }
167
- async deleteMessage(message) {
168
- if (!this.shouldDeleteMessages) {
169
- debug('Skipping message delete since shouldDeleteMessages is set to false');
66
+ if (this.stopped) {
67
+ debug('Consumer was already stopped');
170
68
  return;
171
69
  }
172
- debug('Deleting message %s', message.MessageId);
173
- const deleteParams = {
174
- QueueUrl: this.queueUrl,
175
- ReceiptHandle: message.ReceiptHandle
176
- };
177
- try {
178
- await this.sqs.send(new client_sqs_1.DeleteMessageCommand(deleteParams));
179
- }
180
- catch (err) {
181
- throw toSQSError(err, `SQS delete message failed: ${err.message}`);
182
- }
183
- }
184
- async executeHandler(message) {
185
- let timeout;
186
- let pending;
187
- try {
188
- if (this.handleMessageTimeout) {
189
- [timeout, pending] = createTimeout(this.handleMessageTimeout);
190
- await Promise.race([this.handleMessage(message), pending]);
191
- }
192
- else {
193
- await this.handleMessage(message);
194
- }
195
- }
196
- catch (err) {
197
- if (err instanceof errors_1.TimeoutError) {
198
- err.message = `Message handler timed out after ${this.handleMessageTimeout}ms: Operation timed out.`;
199
- }
200
- else if (err instanceof Error) {
201
- err.message = `Unexpected message handler failure: ${err.message}`;
202
- }
203
- throw err;
204
- }
205
- finally {
206
- clearTimeout(timeout);
70
+ debug('Stopping consumer');
71
+ this.stopped = true;
72
+ if (this.pollingTimeoutId) {
73
+ clearTimeout(this.pollingTimeoutId);
74
+ this.pollingTimeoutId = undefined;
207
75
  }
76
+ this.emit('stopped');
208
77
  }
209
- async changeVisibilityTimeout(message, timeout) {
210
- try {
211
- const input = {
212
- QueueUrl: this.queueUrl,
213
- ReceiptHandle: message.ReceiptHandle,
214
- VisibilityTimeout: timeout
215
- };
216
- return await this.sqs.send(new client_sqs_1.ChangeMessageVisibilityCommand(input));
217
- }
218
- catch (err) {
219
- this.emit('error', toSQSError(err, `Error changing visibility timeout: ${err.message}`), message);
220
- }
78
+ /**
79
+ * Returns the current polling state of the consumer: `true` if it is actively polling, `false` if it is not.
80
+ */
81
+ get isRunning() {
82
+ return !this.stopped;
221
83
  }
84
+ /**
85
+ * Emit one of the consumer's error events depending on the error received.
86
+ * @param err The error object to forward on
87
+ * @param message The message that the error occurred on
88
+ */
222
89
  emitError(err, message) {
223
- if (err.name === errors_1.SQSError.name) {
90
+ if (!message) {
91
+ this.emit('error', err);
92
+ }
93
+ else if (err.name === errors_1.SQSError.name) {
224
94
  this.emit('error', err, message);
225
95
  }
226
96
  else if (err instanceof errors_1.TimeoutError) {
@@ -230,56 +100,121 @@ class Consumer extends events_1.EventEmitter {
230
100
  this.emit('processing_error', err, message);
231
101
  }
232
102
  }
103
+ /**
104
+ * Poll for new messages from SQS
105
+ */
233
106
  poll() {
234
107
  if (this.stopped) {
235
- this.emit('stopped');
108
+ debug('Poll was called while consumer was stopped, cancelling poll...');
236
109
  return;
237
110
  }
238
111
  debug('Polling for messages');
239
- const receiveParams = {
112
+ let currentPollingTimeout = this.pollingWaitTimeMs;
113
+ this.receiveMessage({
240
114
  QueueUrl: this.queueUrl,
241
115
  AttributeNames: this.attributeNames,
242
116
  MessageAttributeNames: this.messageAttributeNames,
243
117
  MaxNumberOfMessages: this.batchSize,
244
118
  WaitTimeSeconds: this.waitTimeSeconds,
245
119
  VisibilityTimeout: this.visibilityTimeout
246
- };
247
- let currentPollingTimeout = this.pollingWaitTimeMs;
248
- this.receiveMessage(receiveParams)
120
+ })
249
121
  .then(this.handleSqsResponse)
250
122
  .catch((err) => {
251
- this.emit('error', err);
252
- if (isConnectionError(err)) {
123
+ this.emitError(err);
124
+ if ((0, errors_1.isConnectionError)(err)) {
253
125
  debug('There was an authentication error. Pausing before retrying.');
254
126
  currentPollingTimeout = this.authenticationErrorTimeout;
255
127
  }
256
128
  return;
257
129
  })
258
130
  .then(() => {
259
- setTimeout(this.poll, currentPollingTimeout);
131
+ if (this.pollingTimeoutId) {
132
+ clearTimeout(this.pollingTimeoutId);
133
+ }
134
+ this.pollingTimeoutId = setTimeout(this.poll, currentPollingTimeout);
260
135
  })
261
136
  .catch((err) => {
262
- this.emit('error', err);
137
+ this.emitError(err);
263
138
  });
264
139
  }
265
- async processMessageBatch(messages) {
266
- messages.forEach((message) => {
140
+ /**
141
+ * Send a request to SQS to retrieve messages
142
+ * @param params The required params to receive messages from SQS
143
+ */
144
+ async receiveMessage(params) {
145
+ try {
146
+ return await this.sqs.send(new client_sqs_1.ReceiveMessageCommand(params));
147
+ }
148
+ catch (err) {
149
+ throw (0, errors_1.toSQSError)(err, `SQS receive message failed: ${err.message}`);
150
+ }
151
+ }
152
+ /**
153
+ * Handles the response from AWS SQS, determining if we should proceed to
154
+ * the message handler.
155
+ * @param response The output from AWS SQS
156
+ */
157
+ async handleSqsResponse(response) {
158
+ if ((0, validation_1.hasMessages)(response)) {
159
+ if (this.handleMessageBatch) {
160
+ await this.processMessageBatch(response.Messages);
161
+ }
162
+ else {
163
+ await Promise.all(response.Messages.map(this.processMessage));
164
+ }
165
+ this.emit('response_processed');
166
+ }
167
+ else if (response) {
168
+ this.emit('empty');
169
+ }
170
+ }
171
+ /**
172
+ * Process a message that has been received from SQS. This will execute the message
173
+ * handler and delete the message once complete.
174
+ * @param message The message that was delivered from SQS
175
+ */
176
+ async processMessage(message) {
177
+ try {
267
178
  this.emit('message_received', message);
268
- });
269
- let heartbeat;
179
+ if (this.heartbeatInterval) {
180
+ this.heartbeatTimeoutId = this.startHeartbeat(message);
181
+ }
182
+ const ackedMessage = await this.executeHandler(message);
183
+ if ((ackedMessage === null || ackedMessage === void 0 ? void 0 : ackedMessage.MessageId) === message.MessageId) {
184
+ await this.deleteMessage(message);
185
+ this.emit('message_processed', message);
186
+ }
187
+ }
188
+ catch (err) {
189
+ this.emitError(err, message);
190
+ if (this.terminateVisibilityTimeout) {
191
+ await this.changeVisibilityTimeout(message, 0);
192
+ }
193
+ }
194
+ finally {
195
+ clearInterval(this.heartbeatTimeoutId);
196
+ this.heartbeatTimeoutId = undefined;
197
+ }
198
+ }
199
+ /**
200
+ * Process a batch of messages from the SQS queue.
201
+ * @param messages The messages that were delivered from SQS
202
+ */
203
+ async processMessageBatch(messages) {
270
204
  try {
205
+ messages.forEach((message) => {
206
+ this.emit('message_received', message);
207
+ });
271
208
  if (this.heartbeatInterval) {
272
- heartbeat = this.startHeartbeat(async () => {
273
- return this.changeVisibilityTimeoutBatch(messages, this.visibilityTimeout);
274
- });
209
+ this.heartbeatTimeoutId = this.startHeartbeat(null, messages);
275
210
  }
276
211
  const ackedMessages = await this.executeBatchHandler(messages);
277
- if (ackedMessages.length > 0) {
212
+ if ((ackedMessages === null || ackedMessages === void 0 ? void 0 : ackedMessages.length) > 0) {
278
213
  await this.deleteMessageBatch(ackedMessages);
214
+ ackedMessages.forEach((message) => {
215
+ this.emit('message_processed', message);
216
+ });
279
217
  }
280
- ackedMessages.forEach((message) => {
281
- this.emit('message_processed', message);
282
- });
283
218
  }
284
219
  catch (err) {
285
220
  this.emit('error', err, messages);
@@ -288,62 +223,154 @@ class Consumer extends events_1.EventEmitter {
288
223
  }
289
224
  }
290
225
  finally {
291
- clearInterval(heartbeat);
226
+ clearInterval(this.heartbeatTimeoutId);
227
+ this.heartbeatTimeoutId = undefined;
292
228
  }
293
229
  }
294
- async deleteMessageBatch(messages) {
295
- if (!this.shouldDeleteMessages) {
296
- debug('Skipping message delete since shouldDeleteMessages is set to false');
297
- return;
230
+ /**
231
+ * Trigger a function on a set interval
232
+ * @param heartbeatFn The function that should be triggered
233
+ */
234
+ startHeartbeat(message, messages) {
235
+ return setInterval(() => {
236
+ if (this.handleMessageBatch) {
237
+ return this.changeVisibilityTimeoutBatch(messages, this.visibilityTimeout);
238
+ }
239
+ else {
240
+ return this.changeVisibilityTimeout(message, this.visibilityTimeout);
241
+ }
242
+ }, this.heartbeatInterval * 1000);
243
+ }
244
+ /**
245
+ * Change the visibility timeout on a message
246
+ * @param message The message to change the value of
247
+ * @param timeout The new timeout that should be set
248
+ */
249
+ async changeVisibilityTimeout(message, timeout) {
250
+ try {
251
+ const input = {
252
+ QueueUrl: this.queueUrl,
253
+ ReceiptHandle: message.ReceiptHandle,
254
+ VisibilityTimeout: timeout
255
+ };
256
+ return await this.sqs.send(new client_sqs_1.ChangeMessageVisibilityCommand(input));
298
257
  }
299
- debug('Deleting messages %s', messages.map((msg) => msg.MessageId).join(' ,'));
300
- const deleteParams = {
258
+ catch (err) {
259
+ this.emit('error', (0, errors_1.toSQSError)(err, `Error changing visibility timeout: ${err.message}`), message);
260
+ }
261
+ }
262
+ /**
263
+ * Change the visibility timeout on a batch of messages
264
+ * @param messages The messages to change the value of
265
+ * @param timeout The new timeout that should be set
266
+ */
267
+ async changeVisibilityTimeoutBatch(messages, timeout) {
268
+ const params = {
301
269
  QueueUrl: this.queueUrl,
302
270
  Entries: messages.map((message) => ({
303
271
  Id: message.MessageId,
304
- ReceiptHandle: message.ReceiptHandle
272
+ ReceiptHandle: message.ReceiptHandle,
273
+ VisibilityTimeout: timeout
305
274
  }))
306
275
  };
307
276
  try {
308
- await this.sqs.send(new client_sqs_1.DeleteMessageBatchCommand(deleteParams));
277
+ return await this.sqs.send(new client_sqs_1.ChangeMessageVisibilityBatchCommand(params));
309
278
  }
310
279
  catch (err) {
311
- throw toSQSError(err, `SQS delete message failed: ${err.message}`);
280
+ this.emit('error', (0, errors_1.toSQSError)(err, `Error changing visibility timeout: ${err.message}`), messages);
312
281
  }
313
282
  }
283
+ /**
284
+ * Trigger the applications handleMessage function
285
+ * @param message The message that was received from SQS
286
+ */
287
+ async executeHandler(message) {
288
+ try {
289
+ let result;
290
+ if (this.handleMessageTimeout) {
291
+ const pending = new Promise((_, reject) => {
292
+ this.handleMessageTimeoutId = setTimeout(() => {
293
+ reject(new errors_1.TimeoutError());
294
+ }, this.handleMessageTimeout);
295
+ });
296
+ result = await Promise.race([this.handleMessage(message), pending]);
297
+ }
298
+ else {
299
+ result = await this.handleMessage(message);
300
+ }
301
+ return result instanceof Object ? result : message;
302
+ }
303
+ catch (err) {
304
+ err.message =
305
+ err instanceof errors_1.TimeoutError
306
+ ? `Message handler timed out after ${this.handleMessageTimeout}ms: Operation timed out.`
307
+ : `Unexpected message handler failure: ${err.message}`;
308
+ throw err;
309
+ }
310
+ finally {
311
+ if (this.handleMessageTimeoutId) {
312
+ clearTimeout(this.handleMessageTimeoutId);
313
+ }
314
+ }
315
+ }
316
+ /**
317
+ * Execute the application's message batch handler
318
+ * @param messages The messages that should be forwarded from the SQS queue
319
+ */
314
320
  async executeBatchHandler(messages) {
315
321
  try {
316
322
  const result = await this.handleMessageBatch(messages);
317
- if (result instanceof Object) {
318
- return result;
319
- }
320
- return messages;
323
+ return result instanceof Object ? result : messages;
321
324
  }
322
325
  catch (err) {
323
326
  err.message = `Unexpected message handler failure: ${err.message}`;
324
327
  throw err;
325
328
  }
326
329
  }
327
- async changeVisibilityTimeoutBatch(messages, timeout) {
328
- const params = {
330
+ /**
331
+ * Delete a single message from SQS
332
+ * @param message The message to delete from the SQS queue
333
+ */
334
+ async deleteMessage(message) {
335
+ if (!this.shouldDeleteMessages) {
336
+ debug('Skipping message delete since shouldDeleteMessages is set to false');
337
+ return;
338
+ }
339
+ debug('Deleting message %s', message.MessageId);
340
+ const deleteParams = {
341
+ QueueUrl: this.queueUrl,
342
+ ReceiptHandle: message.ReceiptHandle
343
+ };
344
+ try {
345
+ await this.sqs.send(new client_sqs_1.DeleteMessageCommand(deleteParams));
346
+ }
347
+ catch (err) {
348
+ throw (0, errors_1.toSQSError)(err, `SQS delete message failed: ${err.message}`);
349
+ }
350
+ }
351
+ /**
352
+ * Delete a batch of messages from the SQS queue.
353
+ * @param messages The messages that should be deleted from SQS
354
+ */
355
+ async deleteMessageBatch(messages) {
356
+ if (!this.shouldDeleteMessages) {
357
+ debug('Skipping message delete since shouldDeleteMessages is set to false');
358
+ return;
359
+ }
360
+ debug('Deleting messages %s', messages.map((msg) => msg.MessageId).join(' ,'));
361
+ const deleteParams = {
329
362
  QueueUrl: this.queueUrl,
330
363
  Entries: messages.map((message) => ({
331
364
  Id: message.MessageId,
332
- ReceiptHandle: message.ReceiptHandle,
333
- VisibilityTimeout: timeout
365
+ ReceiptHandle: message.ReceiptHandle
334
366
  }))
335
367
  };
336
368
  try {
337
- return await this.sqs.send(new client_sqs_1.ChangeMessageVisibilityBatchCommand(params));
369
+ await this.sqs.send(new client_sqs_1.DeleteMessageBatchCommand(deleteParams));
338
370
  }
339
371
  catch (err) {
340
- this.emit('error', toSQSError(err, `Error changing visibility timeout: ${err.message}`), messages);
372
+ throw (0, errors_1.toSQSError)(err, `SQS delete message failed: ${err.message}`);
341
373
  }
342
374
  }
343
- startHeartbeat(heartbeatFn) {
344
- return setInterval(() => {
345
- heartbeatFn();
346
- }, this.heartbeatInterval * 1000);
347
- }
348
375
  }
349
376
  exports.Consumer = Consumer;
package/dist/errors.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { AWSError } from './types';
1
2
  declare class SQSError extends Error {
2
3
  code: string;
3
4
  statusCode: number;
@@ -10,4 +11,15 @@ declare class SQSError extends Error {
10
11
  declare class TimeoutError extends Error {
11
12
  constructor(message?: string);
12
13
  }
13
- export { SQSError, TimeoutError };
14
+ /**
15
+ * Checks if the error provided should be treated as a connection error.
16
+ * @param err The error that was received.
17
+ */
18
+ declare function isConnectionError(err: Error): boolean;
19
+ /**
20
+ * Formats an AWSError the the SQSError type.
21
+ * @param err The error object that was received.
22
+ * @param message The message that the error occurred on.
23
+ */
24
+ declare function toSQSError(err: AWSError, message: string): SQSError;
25
+ export { SQSError, TimeoutError, isConnectionError, toSQSError };
package/dist/errors.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TimeoutError = exports.SQSError = void 0;
3
+ exports.toSQSError = exports.isConnectionError = exports.TimeoutError = exports.SQSError = void 0;
4
4
  class SQSError extends Error {
5
5
  constructor(message) {
6
6
  super(message);
@@ -16,3 +16,34 @@ class TimeoutError extends Error {
16
16
  }
17
17
  }
18
18
  exports.TimeoutError = TimeoutError;
19
+ /**
20
+ * Checks if the error provided should be treated as a connection error.
21
+ * @param err The error that was received.
22
+ */
23
+ function isConnectionError(err) {
24
+ if (err instanceof SQSError) {
25
+ return (err.statusCode === 403 ||
26
+ err.code === 'CredentialsError' ||
27
+ err.code === 'UnknownEndpoint' ||
28
+ err.code === 'AWS.SimpleQueueService.NonExistentQueue');
29
+ }
30
+ return false;
31
+ }
32
+ exports.isConnectionError = isConnectionError;
33
+ /**
34
+ * Formats an AWSError the the SQSError type.
35
+ * @param err The error object that was received.
36
+ * @param message The message that the error occurred on.
37
+ */
38
+ function toSQSError(err, message) {
39
+ var _a, _b;
40
+ const sqsError = new SQSError(message);
41
+ sqsError.code = err.name;
42
+ sqsError.statusCode = (_a = err.$metadata) === null || _a === void 0 ? void 0 : _a.httpStatusCode;
43
+ sqsError.retryable = (_b = err.$retryable) === null || _b === void 0 ? void 0 : _b.throttling;
44
+ sqsError.service = err.$service;
45
+ sqsError.fault = err.$fault;
46
+ sqsError.time = new Date();
47
+ return sqsError;
48
+ }
49
+ exports.toSQSError = toSQSError;