generated from serverless/template-package
-
Notifications
You must be signed in to change notification settings - Fork 10
/
aws-request.js
60 lines (56 loc) · 2.09 KB
/
aws-request.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
'use strict';
const isPlainObject = require('type/plain-object/is');
const isThenable = require('type/thenable/is');
const ensureConstructor = require('type/constructor/ensure');
const ensurePlainObject = require('type/plain-object/ensure');
const memoizeWeak = require('memoizee/weak');
const awsLog = require('log').get('aws');
const wait = require('timers-ext/promise/sleep');
const getClientInstance = memoizeWeak(
(Client, options) => {
const params = { region: 'us-east-1', ...options };
return new Client(params);
},
{ normalizer: (ignore, [options]) => JSON.stringify(options) }
);
const resolveClientData = (clientOrClientConfig) => {
if (isPlainObject(clientOrClientConfig)) {
return [
ensureConstructor(clientOrClientConfig.client),
ensurePlainObject(clientOrClientConfig.params, { default: {} }),
];
}
return [ensureConstructor(clientOrClientConfig), {}];
};
let lastAwsRequestId = 0;
module.exports = function awsRequest(clientOrClientConfig, method, ...args) {
const requestId = ++lastAwsRequestId;
awsLog.debug('[%d] %O %s %O', requestId, clientOrClientConfig, method, args);
const instance = getClientInstance(...resolveClientData(clientOrClientConfig));
const response = instance[method](...args);
const promise = isThenable(response) ? response : response.promise();
return promise.then(
(result) => {
awsLog.debug('[%d] %O', requestId, result);
return result;
},
(error) => {
awsLog.debug('[%d] %O', requestId, error);
const shouldRetry = (() => {
if (error.statusCode === 403) return false;
if (error.retryable) return true;
if (error.Reason === 'CallerRateLimitExceeded') return true;
if (error.message.includes('Rate exceeded')) return true;
if (error.message.includes('Too Many Requests')) return true;
return false;
})();
if (shouldRetry) {
awsLog.debug('[%d] retry', requestId);
return wait(4000 + Math.random() * 3000).then(() =>
awsRequest(clientOrClientConfig, method, ...args)
);
}
throw error;
}
);
};