@smithy/middleware-retry 2.0.26 → 2.1.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.
@@ -1,24 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AdaptiveRetryStrategy = void 0;
4
- const util_retry_1 = require("@smithy/util-retry");
5
- const StandardRetryStrategy_1 = require("./StandardRetryStrategy");
6
- class AdaptiveRetryStrategy extends StandardRetryStrategy_1.StandardRetryStrategy {
7
- constructor(maxAttemptsProvider, options) {
8
- const { rateLimiter, ...superOptions } = options !== null && options !== void 0 ? options : {};
9
- super(maxAttemptsProvider, superOptions);
10
- this.rateLimiter = rateLimiter !== null && rateLimiter !== void 0 ? rateLimiter : new util_retry_1.DefaultRateLimiter();
11
- this.mode = util_retry_1.RETRY_MODES.ADAPTIVE;
12
- }
13
- async retry(next, args) {
14
- return super.retry(next, args, {
15
- beforeRequest: async () => {
16
- return this.rateLimiter.getSendToken();
17
- },
18
- afterRequest: (response) => {
19
- this.rateLimiter.updateClientSendingRate(response);
20
- },
21
- });
22
- }
23
- }
24
- exports.AdaptiveRetryStrategy = AdaptiveRetryStrategy;
1
+ module.exports = require("./index.js");
@@ -1,95 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StandardRetryStrategy = void 0;
4
- const protocol_http_1 = require("@smithy/protocol-http");
5
- const service_error_classification_1 = require("@smithy/service-error-classification");
6
- const util_retry_1 = require("@smithy/util-retry");
7
- const uuid_1 = require("uuid");
8
- const defaultRetryQuota_1 = require("./defaultRetryQuota");
9
- const delayDecider_1 = require("./delayDecider");
10
- const retryDecider_1 = require("./retryDecider");
11
- const util_1 = require("./util");
12
- class StandardRetryStrategy {
13
- constructor(maxAttemptsProvider, options) {
14
- var _a, _b, _c;
15
- this.maxAttemptsProvider = maxAttemptsProvider;
16
- this.mode = util_retry_1.RETRY_MODES.STANDARD;
17
- this.retryDecider = (_a = options === null || options === void 0 ? void 0 : options.retryDecider) !== null && _a !== void 0 ? _a : retryDecider_1.defaultRetryDecider;
18
- this.delayDecider = (_b = options === null || options === void 0 ? void 0 : options.delayDecider) !== null && _b !== void 0 ? _b : delayDecider_1.defaultDelayDecider;
19
- this.retryQuota = (_c = options === null || options === void 0 ? void 0 : options.retryQuota) !== null && _c !== void 0 ? _c : (0, defaultRetryQuota_1.getDefaultRetryQuota)(util_retry_1.INITIAL_RETRY_TOKENS);
20
- }
21
- shouldRetry(error, attempts, maxAttempts) {
22
- return attempts < maxAttempts && this.retryDecider(error) && this.retryQuota.hasRetryTokens(error);
23
- }
24
- async getMaxAttempts() {
25
- let maxAttempts;
26
- try {
27
- maxAttempts = await this.maxAttemptsProvider();
28
- }
29
- catch (error) {
30
- maxAttempts = util_retry_1.DEFAULT_MAX_ATTEMPTS;
31
- }
32
- return maxAttempts;
33
- }
34
- async retry(next, args, options) {
35
- let retryTokenAmount;
36
- let attempts = 0;
37
- let totalDelay = 0;
38
- const maxAttempts = await this.getMaxAttempts();
39
- const { request } = args;
40
- if (protocol_http_1.HttpRequest.isInstance(request)) {
41
- request.headers[util_retry_1.INVOCATION_ID_HEADER] = (0, uuid_1.v4)();
42
- }
43
- while (true) {
44
- try {
45
- if (protocol_http_1.HttpRequest.isInstance(request)) {
46
- request.headers[util_retry_1.REQUEST_HEADER] = `attempt=${attempts + 1}; max=${maxAttempts}`;
47
- }
48
- if (options === null || options === void 0 ? void 0 : options.beforeRequest) {
49
- await options.beforeRequest();
50
- }
51
- const { response, output } = await next(args);
52
- if (options === null || options === void 0 ? void 0 : options.afterRequest) {
53
- options.afterRequest(response);
54
- }
55
- this.retryQuota.releaseRetryTokens(retryTokenAmount);
56
- output.$metadata.attempts = attempts + 1;
57
- output.$metadata.totalRetryDelay = totalDelay;
58
- return { response, output };
59
- }
60
- catch (e) {
61
- const err = (0, util_1.asSdkError)(e);
62
- attempts++;
63
- if (this.shouldRetry(err, attempts, maxAttempts)) {
64
- retryTokenAmount = this.retryQuota.retrieveRetryTokens(err);
65
- const delayFromDecider = this.delayDecider((0, service_error_classification_1.isThrottlingError)(err) ? util_retry_1.THROTTLING_RETRY_DELAY_BASE : util_retry_1.DEFAULT_RETRY_DELAY_BASE, attempts);
66
- const delayFromResponse = getDelayFromRetryAfterHeader(err.$response);
67
- const delay = Math.max(delayFromResponse || 0, delayFromDecider);
68
- totalDelay += delay;
69
- await new Promise((resolve) => setTimeout(resolve, delay));
70
- continue;
71
- }
72
- if (!err.$metadata) {
73
- err.$metadata = {};
74
- }
75
- err.$metadata.attempts = attempts;
76
- err.$metadata.totalRetryDelay = totalDelay;
77
- throw err;
78
- }
79
- }
80
- }
81
- }
82
- exports.StandardRetryStrategy = StandardRetryStrategy;
83
- const getDelayFromRetryAfterHeader = (response) => {
84
- if (!protocol_http_1.HttpResponse.isInstance(response))
85
- return;
86
- const retryAfterHeaderName = Object.keys(response.headers).find((key) => key.toLowerCase() === "retry-after");
87
- if (!retryAfterHeaderName)
88
- return;
89
- const retryAfter = response.headers[retryAfterHeaderName];
90
- const retryAfterSeconds = Number(retryAfter);
91
- if (!Number.isNaN(retryAfterSeconds))
92
- return retryAfterSeconds * 1000;
93
- const retryAfterDate = new Date(retryAfter);
94
- return retryAfterDate.getTime() - Date.now();
95
- };
1
+ module.exports = require("./index.js");
@@ -1,57 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NODE_RETRY_MODE_CONFIG_OPTIONS = exports.CONFIG_RETRY_MODE = exports.ENV_RETRY_MODE = exports.resolveRetryConfig = exports.NODE_MAX_ATTEMPT_CONFIG_OPTIONS = exports.CONFIG_MAX_ATTEMPTS = exports.ENV_MAX_ATTEMPTS = void 0;
4
- const util_middleware_1 = require("@smithy/util-middleware");
5
- const util_retry_1 = require("@smithy/util-retry");
6
- exports.ENV_MAX_ATTEMPTS = "AWS_MAX_ATTEMPTS";
7
- exports.CONFIG_MAX_ATTEMPTS = "max_attempts";
8
- exports.NODE_MAX_ATTEMPT_CONFIG_OPTIONS = {
9
- environmentVariableSelector: (env) => {
10
- const value = env[exports.ENV_MAX_ATTEMPTS];
11
- if (!value)
12
- return undefined;
13
- const maxAttempt = parseInt(value);
14
- if (Number.isNaN(maxAttempt)) {
15
- throw new Error(`Environment variable ${exports.ENV_MAX_ATTEMPTS} mast be a number, got "${value}"`);
16
- }
17
- return maxAttempt;
18
- },
19
- configFileSelector: (profile) => {
20
- const value = profile[exports.CONFIG_MAX_ATTEMPTS];
21
- if (!value)
22
- return undefined;
23
- const maxAttempt = parseInt(value);
24
- if (Number.isNaN(maxAttempt)) {
25
- throw new Error(`Shared config file entry ${exports.CONFIG_MAX_ATTEMPTS} mast be a number, got "${value}"`);
26
- }
27
- return maxAttempt;
28
- },
29
- default: util_retry_1.DEFAULT_MAX_ATTEMPTS,
30
- };
31
- const resolveRetryConfig = (input) => {
32
- var _a;
33
- const { retryStrategy } = input;
34
- const maxAttempts = (0, util_middleware_1.normalizeProvider)((_a = input.maxAttempts) !== null && _a !== void 0 ? _a : util_retry_1.DEFAULT_MAX_ATTEMPTS);
35
- return {
36
- ...input,
37
- maxAttempts,
38
- retryStrategy: async () => {
39
- if (retryStrategy) {
40
- return retryStrategy;
41
- }
42
- const retryMode = await (0, util_middleware_1.normalizeProvider)(input.retryMode)();
43
- if (retryMode === util_retry_1.RETRY_MODES.ADAPTIVE) {
44
- return new util_retry_1.AdaptiveRetryStrategy(maxAttempts);
45
- }
46
- return new util_retry_1.StandardRetryStrategy(maxAttempts);
47
- },
48
- };
49
- };
50
- exports.resolveRetryConfig = resolveRetryConfig;
51
- exports.ENV_RETRY_MODE = "AWS_RETRY_MODE";
52
- exports.CONFIG_RETRY_MODE = "retry_mode";
53
- exports.NODE_RETRY_MODE_CONFIG_OPTIONS = {
54
- environmentVariableSelector: (env) => env[exports.ENV_RETRY_MODE],
55
- configFileSelector: (profile) => profile[exports.CONFIG_RETRY_MODE],
56
- default: util_retry_1.DEFAULT_RETRY_MODE,
57
- };
1
+ module.exports = require("./index.js");
@@ -1,32 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getDefaultRetryQuota = void 0;
4
- const util_retry_1 = require("@smithy/util-retry");
5
- const getDefaultRetryQuota = (initialRetryTokens, options) => {
6
- var _a, _b, _c;
7
- const MAX_CAPACITY = initialRetryTokens;
8
- const noRetryIncrement = (_a = options === null || options === void 0 ? void 0 : options.noRetryIncrement) !== null && _a !== void 0 ? _a : util_retry_1.NO_RETRY_INCREMENT;
9
- const retryCost = (_b = options === null || options === void 0 ? void 0 : options.retryCost) !== null && _b !== void 0 ? _b : util_retry_1.RETRY_COST;
10
- const timeoutRetryCost = (_c = options === null || options === void 0 ? void 0 : options.timeoutRetryCost) !== null && _c !== void 0 ? _c : util_retry_1.TIMEOUT_RETRY_COST;
11
- let availableCapacity = initialRetryTokens;
12
- const getCapacityAmount = (error) => (error.name === "TimeoutError" ? timeoutRetryCost : retryCost);
13
- const hasRetryTokens = (error) => getCapacityAmount(error) <= availableCapacity;
14
- const retrieveRetryTokens = (error) => {
15
- if (!hasRetryTokens(error)) {
16
- throw new Error("No retry token available");
17
- }
18
- const capacityAmount = getCapacityAmount(error);
19
- availableCapacity -= capacityAmount;
20
- return capacityAmount;
21
- };
22
- const releaseRetryTokens = (capacityReleaseAmount) => {
23
- availableCapacity += capacityReleaseAmount !== null && capacityReleaseAmount !== void 0 ? capacityReleaseAmount : noRetryIncrement;
24
- availableCapacity = Math.min(availableCapacity, MAX_CAPACITY);
25
- };
26
- return Object.freeze({
27
- hasRetryTokens,
28
- retrieveRetryTokens,
29
- releaseRetryTokens,
30
- });
31
- };
32
- exports.getDefaultRetryQuota = getDefaultRetryQuota;
1
+ module.exports = require("./index.js");
@@ -1,6 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultDelayDecider = void 0;
4
- const util_retry_1 = require("@smithy/util-retry");
5
- const defaultDelayDecider = (delayBase, attempts) => Math.floor(Math.min(util_retry_1.MAXIMUM_RETRY_DELAY, Math.random() * 2 ** attempts * delayBase));
6
- exports.defaultDelayDecider = defaultDelayDecider;
1
+ module.exports = require("./index.js");
package/dist-cjs/index.js CHANGED
@@ -1,10 +1,422 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- tslib_1.__exportStar(require("./AdaptiveRetryStrategy"), exports);
5
- tslib_1.__exportStar(require("./StandardRetryStrategy"), exports);
6
- tslib_1.__exportStar(require("./configurations"), exports);
7
- tslib_1.__exportStar(require("./delayDecider"), exports);
8
- tslib_1.__exportStar(require("./omitRetryHeadersMiddleware"), exports);
9
- tslib_1.__exportStar(require("./retryDecider"), exports);
10
- tslib_1.__exportStar(require("./retryMiddleware"), exports);
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ AdaptiveRetryStrategy: () => AdaptiveRetryStrategy,
24
+ CONFIG_MAX_ATTEMPTS: () => CONFIG_MAX_ATTEMPTS,
25
+ CONFIG_RETRY_MODE: () => CONFIG_RETRY_MODE,
26
+ ENV_MAX_ATTEMPTS: () => ENV_MAX_ATTEMPTS,
27
+ ENV_RETRY_MODE: () => ENV_RETRY_MODE,
28
+ NODE_MAX_ATTEMPT_CONFIG_OPTIONS: () => NODE_MAX_ATTEMPT_CONFIG_OPTIONS,
29
+ NODE_RETRY_MODE_CONFIG_OPTIONS: () => NODE_RETRY_MODE_CONFIG_OPTIONS,
30
+ StandardRetryStrategy: () => StandardRetryStrategy,
31
+ defaultDelayDecider: () => defaultDelayDecider,
32
+ defaultRetryDecider: () => defaultRetryDecider,
33
+ getOmitRetryHeadersPlugin: () => getOmitRetryHeadersPlugin,
34
+ getRetryAfterHint: () => getRetryAfterHint,
35
+ getRetryPlugin: () => getRetryPlugin,
36
+ omitRetryHeadersMiddleware: () => omitRetryHeadersMiddleware,
37
+ omitRetryHeadersMiddlewareOptions: () => omitRetryHeadersMiddlewareOptions,
38
+ resolveRetryConfig: () => resolveRetryConfig,
39
+ retryMiddleware: () => retryMiddleware,
40
+ retryMiddlewareOptions: () => retryMiddlewareOptions
41
+ });
42
+ module.exports = __toCommonJS(src_exports);
43
+
44
+ // src/AdaptiveRetryStrategy.ts
45
+
46
+
47
+ // src/StandardRetryStrategy.ts
48
+ var import_protocol_http = require("@smithy/protocol-http");
49
+
50
+
51
+ var import_uuid = require("uuid");
52
+
53
+ // src/defaultRetryQuota.ts
54
+ var import_util_retry = require("@smithy/util-retry");
55
+ var getDefaultRetryQuota = /* @__PURE__ */ __name((initialRetryTokens, options) => {
56
+ const MAX_CAPACITY = initialRetryTokens;
57
+ const noRetryIncrement = (options == null ? void 0 : options.noRetryIncrement) ?? import_util_retry.NO_RETRY_INCREMENT;
58
+ const retryCost = (options == null ? void 0 : options.retryCost) ?? import_util_retry.RETRY_COST;
59
+ const timeoutRetryCost = (options == null ? void 0 : options.timeoutRetryCost) ?? import_util_retry.TIMEOUT_RETRY_COST;
60
+ let availableCapacity = initialRetryTokens;
61
+ const getCapacityAmount = /* @__PURE__ */ __name((error) => error.name === "TimeoutError" ? timeoutRetryCost : retryCost, "getCapacityAmount");
62
+ const hasRetryTokens = /* @__PURE__ */ __name((error) => getCapacityAmount(error) <= availableCapacity, "hasRetryTokens");
63
+ const retrieveRetryTokens = /* @__PURE__ */ __name((error) => {
64
+ if (!hasRetryTokens(error)) {
65
+ throw new Error("No retry token available");
66
+ }
67
+ const capacityAmount = getCapacityAmount(error);
68
+ availableCapacity -= capacityAmount;
69
+ return capacityAmount;
70
+ }, "retrieveRetryTokens");
71
+ const releaseRetryTokens = /* @__PURE__ */ __name((capacityReleaseAmount) => {
72
+ availableCapacity += capacityReleaseAmount ?? noRetryIncrement;
73
+ availableCapacity = Math.min(availableCapacity, MAX_CAPACITY);
74
+ }, "releaseRetryTokens");
75
+ return Object.freeze({
76
+ hasRetryTokens,
77
+ retrieveRetryTokens,
78
+ releaseRetryTokens
79
+ });
80
+ }, "getDefaultRetryQuota");
81
+
82
+ // src/delayDecider.ts
83
+
84
+ var defaultDelayDecider = /* @__PURE__ */ __name((delayBase, attempts) => Math.floor(Math.min(import_util_retry.MAXIMUM_RETRY_DELAY, Math.random() * 2 ** attempts * delayBase)), "defaultDelayDecider");
85
+
86
+ // src/retryDecider.ts
87
+ var import_service_error_classification = require("@smithy/service-error-classification");
88
+ var defaultRetryDecider = /* @__PURE__ */ __name((error) => {
89
+ if (!error) {
90
+ return false;
91
+ }
92
+ return (0, import_service_error_classification.isRetryableByTrait)(error) || (0, import_service_error_classification.isClockSkewError)(error) || (0, import_service_error_classification.isThrottlingError)(error) || (0, import_service_error_classification.isTransientError)(error);
93
+ }, "defaultRetryDecider");
94
+
95
+ // src/util.ts
96
+ var asSdkError = /* @__PURE__ */ __name((error) => {
97
+ if (error instanceof Error)
98
+ return error;
99
+ if (error instanceof Object)
100
+ return Object.assign(new Error(), error);
101
+ if (typeof error === "string")
102
+ return new Error(error);
103
+ return new Error(`AWS SDK error wrapper for ${error}`);
104
+ }, "asSdkError");
105
+
106
+ // src/StandardRetryStrategy.ts
107
+ var _StandardRetryStrategy = class _StandardRetryStrategy {
108
+ constructor(maxAttemptsProvider, options) {
109
+ this.maxAttemptsProvider = maxAttemptsProvider;
110
+ this.mode = import_util_retry.RETRY_MODES.STANDARD;
111
+ this.retryDecider = (options == null ? void 0 : options.retryDecider) ?? defaultRetryDecider;
112
+ this.delayDecider = (options == null ? void 0 : options.delayDecider) ?? defaultDelayDecider;
113
+ this.retryQuota = (options == null ? void 0 : options.retryQuota) ?? getDefaultRetryQuota(import_util_retry.INITIAL_RETRY_TOKENS);
114
+ }
115
+ shouldRetry(error, attempts, maxAttempts) {
116
+ return attempts < maxAttempts && this.retryDecider(error) && this.retryQuota.hasRetryTokens(error);
117
+ }
118
+ async getMaxAttempts() {
119
+ let maxAttempts;
120
+ try {
121
+ maxAttempts = await this.maxAttemptsProvider();
122
+ } catch (error) {
123
+ maxAttempts = import_util_retry.DEFAULT_MAX_ATTEMPTS;
124
+ }
125
+ return maxAttempts;
126
+ }
127
+ async retry(next, args, options) {
128
+ let retryTokenAmount;
129
+ let attempts = 0;
130
+ let totalDelay = 0;
131
+ const maxAttempts = await this.getMaxAttempts();
132
+ const { request } = args;
133
+ if (import_protocol_http.HttpRequest.isInstance(request)) {
134
+ request.headers[import_util_retry.INVOCATION_ID_HEADER] = (0, import_uuid.v4)();
135
+ }
136
+ while (true) {
137
+ try {
138
+ if (import_protocol_http.HttpRequest.isInstance(request)) {
139
+ request.headers[import_util_retry.REQUEST_HEADER] = `attempt=${attempts + 1}; max=${maxAttempts}`;
140
+ }
141
+ if (options == null ? void 0 : options.beforeRequest) {
142
+ await options.beforeRequest();
143
+ }
144
+ const { response, output } = await next(args);
145
+ if (options == null ? void 0 : options.afterRequest) {
146
+ options.afterRequest(response);
147
+ }
148
+ this.retryQuota.releaseRetryTokens(retryTokenAmount);
149
+ output.$metadata.attempts = attempts + 1;
150
+ output.$metadata.totalRetryDelay = totalDelay;
151
+ return { response, output };
152
+ } catch (e) {
153
+ const err = asSdkError(e);
154
+ attempts++;
155
+ if (this.shouldRetry(err, attempts, maxAttempts)) {
156
+ retryTokenAmount = this.retryQuota.retrieveRetryTokens(err);
157
+ const delayFromDecider = this.delayDecider(
158
+ (0, import_service_error_classification.isThrottlingError)(err) ? import_util_retry.THROTTLING_RETRY_DELAY_BASE : import_util_retry.DEFAULT_RETRY_DELAY_BASE,
159
+ attempts
160
+ );
161
+ const delayFromResponse = getDelayFromRetryAfterHeader(err.$response);
162
+ const delay = Math.max(delayFromResponse || 0, delayFromDecider);
163
+ totalDelay += delay;
164
+ await new Promise((resolve) => setTimeout(resolve, delay));
165
+ continue;
166
+ }
167
+ if (!err.$metadata) {
168
+ err.$metadata = {};
169
+ }
170
+ err.$metadata.attempts = attempts;
171
+ err.$metadata.totalRetryDelay = totalDelay;
172
+ throw err;
173
+ }
174
+ }
175
+ }
176
+ };
177
+ __name(_StandardRetryStrategy, "StandardRetryStrategy");
178
+ var StandardRetryStrategy = _StandardRetryStrategy;
179
+ var getDelayFromRetryAfterHeader = /* @__PURE__ */ __name((response) => {
180
+ if (!import_protocol_http.HttpResponse.isInstance(response))
181
+ return;
182
+ const retryAfterHeaderName = Object.keys(response.headers).find((key) => key.toLowerCase() === "retry-after");
183
+ if (!retryAfterHeaderName)
184
+ return;
185
+ const retryAfter = response.headers[retryAfterHeaderName];
186
+ const retryAfterSeconds = Number(retryAfter);
187
+ if (!Number.isNaN(retryAfterSeconds))
188
+ return retryAfterSeconds * 1e3;
189
+ const retryAfterDate = new Date(retryAfter);
190
+ return retryAfterDate.getTime() - Date.now();
191
+ }, "getDelayFromRetryAfterHeader");
192
+
193
+ // src/AdaptiveRetryStrategy.ts
194
+ var _AdaptiveRetryStrategy = class _AdaptiveRetryStrategy extends StandardRetryStrategy {
195
+ constructor(maxAttemptsProvider, options) {
196
+ const { rateLimiter, ...superOptions } = options ?? {};
197
+ super(maxAttemptsProvider, superOptions);
198
+ this.rateLimiter = rateLimiter ?? new import_util_retry.DefaultRateLimiter();
199
+ this.mode = import_util_retry.RETRY_MODES.ADAPTIVE;
200
+ }
201
+ async retry(next, args) {
202
+ return super.retry(next, args, {
203
+ beforeRequest: async () => {
204
+ return this.rateLimiter.getSendToken();
205
+ },
206
+ afterRequest: (response) => {
207
+ this.rateLimiter.updateClientSendingRate(response);
208
+ }
209
+ });
210
+ }
211
+ };
212
+ __name(_AdaptiveRetryStrategy, "AdaptiveRetryStrategy");
213
+ var AdaptiveRetryStrategy = _AdaptiveRetryStrategy;
214
+
215
+ // src/configurations.ts
216
+ var import_util_middleware = require("@smithy/util-middleware");
217
+
218
+ var ENV_MAX_ATTEMPTS = "AWS_MAX_ATTEMPTS";
219
+ var CONFIG_MAX_ATTEMPTS = "max_attempts";
220
+ var NODE_MAX_ATTEMPT_CONFIG_OPTIONS = {
221
+ environmentVariableSelector: (env) => {
222
+ const value = env[ENV_MAX_ATTEMPTS];
223
+ if (!value)
224
+ return void 0;
225
+ const maxAttempt = parseInt(value);
226
+ if (Number.isNaN(maxAttempt)) {
227
+ throw new Error(`Environment variable ${ENV_MAX_ATTEMPTS} mast be a number, got "${value}"`);
228
+ }
229
+ return maxAttempt;
230
+ },
231
+ configFileSelector: (profile) => {
232
+ const value = profile[CONFIG_MAX_ATTEMPTS];
233
+ if (!value)
234
+ return void 0;
235
+ const maxAttempt = parseInt(value);
236
+ if (Number.isNaN(maxAttempt)) {
237
+ throw new Error(`Shared config file entry ${CONFIG_MAX_ATTEMPTS} mast be a number, got "${value}"`);
238
+ }
239
+ return maxAttempt;
240
+ },
241
+ default: import_util_retry.DEFAULT_MAX_ATTEMPTS
242
+ };
243
+ var resolveRetryConfig = /* @__PURE__ */ __name((input) => {
244
+ const { retryStrategy } = input;
245
+ const maxAttempts = (0, import_util_middleware.normalizeProvider)(input.maxAttempts ?? import_util_retry.DEFAULT_MAX_ATTEMPTS);
246
+ return {
247
+ ...input,
248
+ maxAttempts,
249
+ retryStrategy: async () => {
250
+ if (retryStrategy) {
251
+ return retryStrategy;
252
+ }
253
+ const retryMode = await (0, import_util_middleware.normalizeProvider)(input.retryMode)();
254
+ if (retryMode === import_util_retry.RETRY_MODES.ADAPTIVE) {
255
+ return new import_util_retry.AdaptiveRetryStrategy(maxAttempts);
256
+ }
257
+ return new import_util_retry.StandardRetryStrategy(maxAttempts);
258
+ }
259
+ };
260
+ }, "resolveRetryConfig");
261
+ var ENV_RETRY_MODE = "AWS_RETRY_MODE";
262
+ var CONFIG_RETRY_MODE = "retry_mode";
263
+ var NODE_RETRY_MODE_CONFIG_OPTIONS = {
264
+ environmentVariableSelector: (env) => env[ENV_RETRY_MODE],
265
+ configFileSelector: (profile) => profile[CONFIG_RETRY_MODE],
266
+ default: import_util_retry.DEFAULT_RETRY_MODE
267
+ };
268
+
269
+ // src/omitRetryHeadersMiddleware.ts
270
+
271
+
272
+ var omitRetryHeadersMiddleware = /* @__PURE__ */ __name(() => (next) => async (args) => {
273
+ const { request } = args;
274
+ if (import_protocol_http.HttpRequest.isInstance(request)) {
275
+ delete request.headers[import_util_retry.INVOCATION_ID_HEADER];
276
+ delete request.headers[import_util_retry.REQUEST_HEADER];
277
+ }
278
+ return next(args);
279
+ }, "omitRetryHeadersMiddleware");
280
+ var omitRetryHeadersMiddlewareOptions = {
281
+ name: "omitRetryHeadersMiddleware",
282
+ tags: ["RETRY", "HEADERS", "OMIT_RETRY_HEADERS"],
283
+ relation: "before",
284
+ toMiddleware: "awsAuthMiddleware",
285
+ override: true
286
+ };
287
+ var getOmitRetryHeadersPlugin = /* @__PURE__ */ __name((options) => ({
288
+ applyToStack: (clientStack) => {
289
+ clientStack.addRelativeTo(omitRetryHeadersMiddleware(), omitRetryHeadersMiddlewareOptions);
290
+ }
291
+ }), "getOmitRetryHeadersPlugin");
292
+
293
+ // src/retryMiddleware.ts
294
+
295
+
296
+ var import_smithy_client = require("@smithy/smithy-client");
297
+
298
+
299
+ var import_isStreamingPayload = require("./isStreamingPayload/isStreamingPayload");
300
+ var retryMiddleware = /* @__PURE__ */ __name((options) => (next, context) => async (args) => {
301
+ var _a;
302
+ let retryStrategy = await options.retryStrategy();
303
+ const maxAttempts = await options.maxAttempts();
304
+ if (isRetryStrategyV2(retryStrategy)) {
305
+ retryStrategy = retryStrategy;
306
+ let retryToken = await retryStrategy.acquireInitialRetryToken(context["partition_id"]);
307
+ let lastError = new Error();
308
+ let attempts = 0;
309
+ let totalRetryDelay = 0;
310
+ const { request } = args;
311
+ const isRequest = import_protocol_http.HttpRequest.isInstance(request);
312
+ if (isRequest) {
313
+ request.headers[import_util_retry.INVOCATION_ID_HEADER] = (0, import_uuid.v4)();
314
+ }
315
+ while (true) {
316
+ try {
317
+ if (isRequest) {
318
+ request.headers[import_util_retry.REQUEST_HEADER] = `attempt=${attempts + 1}; max=${maxAttempts}`;
319
+ }
320
+ const { response, output } = await next(args);
321
+ retryStrategy.recordSuccess(retryToken);
322
+ output.$metadata.attempts = attempts + 1;
323
+ output.$metadata.totalRetryDelay = totalRetryDelay;
324
+ return { response, output };
325
+ } catch (e) {
326
+ const retryErrorInfo = getRetryErrorInfo(e);
327
+ lastError = asSdkError(e);
328
+ if (isRequest && (0, import_isStreamingPayload.isStreamingPayload)(request)) {
329
+ (_a = context.logger instanceof import_smithy_client.NoOpLogger ? console : context.logger) == null ? void 0 : _a.warn(
330
+ "An error was encountered in a non-retryable streaming request."
331
+ );
332
+ throw lastError;
333
+ }
334
+ try {
335
+ retryToken = await retryStrategy.refreshRetryTokenForRetry(retryToken, retryErrorInfo);
336
+ } catch (refreshError) {
337
+ if (!lastError.$metadata) {
338
+ lastError.$metadata = {};
339
+ }
340
+ lastError.$metadata.attempts = attempts + 1;
341
+ lastError.$metadata.totalRetryDelay = totalRetryDelay;
342
+ throw lastError;
343
+ }
344
+ attempts = retryToken.getRetryCount();
345
+ const delay = retryToken.getRetryDelay();
346
+ totalRetryDelay += delay;
347
+ await new Promise((resolve) => setTimeout(resolve, delay));
348
+ }
349
+ }
350
+ } else {
351
+ retryStrategy = retryStrategy;
352
+ if (retryStrategy == null ? void 0 : retryStrategy.mode)
353
+ context.userAgent = [...context.userAgent || [], ["cfg/retry-mode", retryStrategy.mode]];
354
+ return retryStrategy.retry(next, args);
355
+ }
356
+ }, "retryMiddleware");
357
+ var isRetryStrategyV2 = /* @__PURE__ */ __name((retryStrategy) => typeof retryStrategy.acquireInitialRetryToken !== "undefined" && typeof retryStrategy.refreshRetryTokenForRetry !== "undefined" && typeof retryStrategy.recordSuccess !== "undefined", "isRetryStrategyV2");
358
+ var getRetryErrorInfo = /* @__PURE__ */ __name((error) => {
359
+ const errorInfo = {
360
+ errorType: getRetryErrorType(error)
361
+ };
362
+ const retryAfterHint = getRetryAfterHint(error.$response);
363
+ if (retryAfterHint) {
364
+ errorInfo.retryAfterHint = retryAfterHint;
365
+ }
366
+ return errorInfo;
367
+ }, "getRetryErrorInfo");
368
+ var getRetryErrorType = /* @__PURE__ */ __name((error) => {
369
+ if ((0, import_service_error_classification.isThrottlingError)(error))
370
+ return "THROTTLING";
371
+ if ((0, import_service_error_classification.isTransientError)(error))
372
+ return "TRANSIENT";
373
+ if ((0, import_service_error_classification.isServerError)(error))
374
+ return "SERVER_ERROR";
375
+ return "CLIENT_ERROR";
376
+ }, "getRetryErrorType");
377
+ var retryMiddlewareOptions = {
378
+ name: "retryMiddleware",
379
+ tags: ["RETRY"],
380
+ step: "finalizeRequest",
381
+ priority: "high",
382
+ override: true
383
+ };
384
+ var getRetryPlugin = /* @__PURE__ */ __name((options) => ({
385
+ applyToStack: (clientStack) => {
386
+ clientStack.add(retryMiddleware(options), retryMiddlewareOptions);
387
+ }
388
+ }), "getRetryPlugin");
389
+ var getRetryAfterHint = /* @__PURE__ */ __name((response) => {
390
+ if (!import_protocol_http.HttpResponse.isInstance(response))
391
+ return;
392
+ const retryAfterHeaderName = Object.keys(response.headers).find((key) => key.toLowerCase() === "retry-after");
393
+ if (!retryAfterHeaderName)
394
+ return;
395
+ const retryAfter = response.headers[retryAfterHeaderName];
396
+ const retryAfterSeconds = Number(retryAfter);
397
+ if (!Number.isNaN(retryAfterSeconds))
398
+ return new Date(retryAfterSeconds * 1e3);
399
+ const retryAfterDate = new Date(retryAfter);
400
+ return retryAfterDate;
401
+ }, "getRetryAfterHint");
402
+ // Annotate the CommonJS export names for ESM import in node:
403
+ 0 && (module.exports = {
404
+ AdaptiveRetryStrategy,
405
+ CONFIG_MAX_ATTEMPTS,
406
+ CONFIG_RETRY_MODE,
407
+ ENV_MAX_ATTEMPTS,
408
+ ENV_RETRY_MODE,
409
+ NODE_MAX_ATTEMPT_CONFIG_OPTIONS,
410
+ NODE_RETRY_MODE_CONFIG_OPTIONS,
411
+ StandardRetryStrategy,
412
+ defaultDelayDecider,
413
+ defaultRetryDecider,
414
+ getOmitRetryHeadersPlugin,
415
+ getRetryAfterHint,
416
+ getRetryPlugin,
417
+ omitRetryHeadersMiddleware,
418
+ omitRetryHeadersMiddlewareOptions,
419
+ resolveRetryConfig,
420
+ retryMiddleware,
421
+ retryMiddlewareOptions
422
+ });
@@ -1,27 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getOmitRetryHeadersPlugin = exports.omitRetryHeadersMiddlewareOptions = exports.omitRetryHeadersMiddleware = void 0;
4
- const protocol_http_1 = require("@smithy/protocol-http");
5
- const util_retry_1 = require("@smithy/util-retry");
6
- const omitRetryHeadersMiddleware = () => (next) => async (args) => {
7
- const { request } = args;
8
- if (protocol_http_1.HttpRequest.isInstance(request)) {
9
- delete request.headers[util_retry_1.INVOCATION_ID_HEADER];
10
- delete request.headers[util_retry_1.REQUEST_HEADER];
11
- }
12
- return next(args);
13
- };
14
- exports.omitRetryHeadersMiddleware = omitRetryHeadersMiddleware;
15
- exports.omitRetryHeadersMiddlewareOptions = {
16
- name: "omitRetryHeadersMiddleware",
17
- tags: ["RETRY", "HEADERS", "OMIT_RETRY_HEADERS"],
18
- relation: "before",
19
- toMiddleware: "awsAuthMiddleware",
20
- override: true,
21
- };
22
- const getOmitRetryHeadersPlugin = (options) => ({
23
- applyToStack: (clientStack) => {
24
- clientStack.addRelativeTo((0, exports.omitRetryHeadersMiddleware)(), exports.omitRetryHeadersMiddlewareOptions);
25
- },
26
- });
27
- exports.getOmitRetryHeadersPlugin = getOmitRetryHeadersPlugin;
1
+ module.exports = require("./index.js");
@@ -1,11 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultRetryDecider = void 0;
4
- const service_error_classification_1 = require("@smithy/service-error-classification");
5
- const defaultRetryDecider = (error) => {
6
- if (!error) {
7
- return false;
8
- }
9
- return (0, service_error_classification_1.isRetryableByTrait)(error) || (0, service_error_classification_1.isClockSkewError)(error) || (0, service_error_classification_1.isThrottlingError)(error) || (0, service_error_classification_1.isTransientError)(error);
10
- };
11
- exports.defaultRetryDecider = defaultRetryDecider;
1
+ module.exports = require("./index.js");
@@ -1,118 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRetryAfterHint = exports.getRetryPlugin = exports.retryMiddlewareOptions = exports.retryMiddleware = void 0;
4
- const protocol_http_1 = require("@smithy/protocol-http");
5
- const service_error_classification_1 = require("@smithy/service-error-classification");
6
- const smithy_client_1 = require("@smithy/smithy-client");
7
- const util_retry_1 = require("@smithy/util-retry");
8
- const uuid_1 = require("uuid");
9
- const isStreamingPayload_1 = require("./isStreamingPayload/isStreamingPayload");
10
- const util_1 = require("./util");
11
- const retryMiddleware = (options) => (next, context) => async (args) => {
12
- var _a;
13
- let retryStrategy = await options.retryStrategy();
14
- const maxAttempts = await options.maxAttempts();
15
- if (isRetryStrategyV2(retryStrategy)) {
16
- retryStrategy = retryStrategy;
17
- let retryToken = await retryStrategy.acquireInitialRetryToken(context["partition_id"]);
18
- let lastError = new Error();
19
- let attempts = 0;
20
- let totalRetryDelay = 0;
21
- const { request } = args;
22
- const isRequest = protocol_http_1.HttpRequest.isInstance(request);
23
- if (isRequest) {
24
- request.headers[util_retry_1.INVOCATION_ID_HEADER] = (0, uuid_1.v4)();
25
- }
26
- while (true) {
27
- try {
28
- if (isRequest) {
29
- request.headers[util_retry_1.REQUEST_HEADER] = `attempt=${attempts + 1}; max=${maxAttempts}`;
30
- }
31
- const { response, output } = await next(args);
32
- retryStrategy.recordSuccess(retryToken);
33
- output.$metadata.attempts = attempts + 1;
34
- output.$metadata.totalRetryDelay = totalRetryDelay;
35
- return { response, output };
36
- }
37
- catch (e) {
38
- const retryErrorInfo = getRetryErrorInfo(e);
39
- lastError = (0, util_1.asSdkError)(e);
40
- if (isRequest && (0, isStreamingPayload_1.isStreamingPayload)(request)) {
41
- (_a = (context.logger instanceof smithy_client_1.NoOpLogger ? console : context.logger)) === null || _a === void 0 ? void 0 : _a.warn("An error was encountered in a non-retryable streaming request.");
42
- throw lastError;
43
- }
44
- try {
45
- retryToken = await retryStrategy.refreshRetryTokenForRetry(retryToken, retryErrorInfo);
46
- }
47
- catch (refreshError) {
48
- if (!lastError.$metadata) {
49
- lastError.$metadata = {};
50
- }
51
- lastError.$metadata.attempts = attempts + 1;
52
- lastError.$metadata.totalRetryDelay = totalRetryDelay;
53
- throw lastError;
54
- }
55
- attempts = retryToken.getRetryCount();
56
- const delay = retryToken.getRetryDelay();
57
- totalRetryDelay += delay;
58
- await new Promise((resolve) => setTimeout(resolve, delay));
59
- }
60
- }
61
- }
62
- else {
63
- retryStrategy = retryStrategy;
64
- if (retryStrategy === null || retryStrategy === void 0 ? void 0 : retryStrategy.mode)
65
- context.userAgent = [...(context.userAgent || []), ["cfg/retry-mode", retryStrategy.mode]];
66
- return retryStrategy.retry(next, args);
67
- }
68
- };
69
- exports.retryMiddleware = retryMiddleware;
70
- const isRetryStrategyV2 = (retryStrategy) => typeof retryStrategy.acquireInitialRetryToken !== "undefined" &&
71
- typeof retryStrategy.refreshRetryTokenForRetry !== "undefined" &&
72
- typeof retryStrategy.recordSuccess !== "undefined";
73
- const getRetryErrorInfo = (error) => {
74
- const errorInfo = {
75
- errorType: getRetryErrorType(error),
76
- };
77
- const retryAfterHint = (0, exports.getRetryAfterHint)(error.$response);
78
- if (retryAfterHint) {
79
- errorInfo.retryAfterHint = retryAfterHint;
80
- }
81
- return errorInfo;
82
- };
83
- const getRetryErrorType = (error) => {
84
- if ((0, service_error_classification_1.isThrottlingError)(error))
85
- return "THROTTLING";
86
- if ((0, service_error_classification_1.isTransientError)(error))
87
- return "TRANSIENT";
88
- if ((0, service_error_classification_1.isServerError)(error))
89
- return "SERVER_ERROR";
90
- return "CLIENT_ERROR";
91
- };
92
- exports.retryMiddlewareOptions = {
93
- name: "retryMiddleware",
94
- tags: ["RETRY"],
95
- step: "finalizeRequest",
96
- priority: "high",
97
- override: true,
98
- };
99
- const getRetryPlugin = (options) => ({
100
- applyToStack: (clientStack) => {
101
- clientStack.add((0, exports.retryMiddleware)(options), exports.retryMiddlewareOptions);
102
- },
103
- });
104
- exports.getRetryPlugin = getRetryPlugin;
105
- const getRetryAfterHint = (response) => {
106
- if (!protocol_http_1.HttpResponse.isInstance(response))
107
- return;
108
- const retryAfterHeaderName = Object.keys(response.headers).find((key) => key.toLowerCase() === "retry-after");
109
- if (!retryAfterHeaderName)
110
- return;
111
- const retryAfter = response.headers[retryAfterHeaderName];
112
- const retryAfterSeconds = Number(retryAfter);
113
- if (!Number.isNaN(retryAfterSeconds))
114
- return new Date(retryAfterSeconds * 1000);
115
- const retryAfterDate = new Date(retryAfter);
116
- return retryAfterDate;
117
- };
118
- exports.getRetryAfterHint = getRetryAfterHint;
1
+ module.exports = require("./index.js");
package/dist-cjs/types.js CHANGED
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ module.exports = require("./index.js");
package/dist-cjs/util.js CHANGED
@@ -1,13 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.asSdkError = void 0;
4
- const asSdkError = (error) => {
5
- if (error instanceof Error)
6
- return error;
7
- if (error instanceof Object)
8
- return Object.assign(new Error(), error);
9
- if (typeof error === "string")
10
- return new Error(error);
11
- return new Error(`AWS SDK error wrapper for ${error}`);
12
- };
13
- exports.asSdkError = asSdkError;
1
+ module.exports = require("./index.js");
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@smithy/middleware-retry",
3
- "version": "2.0.26",
3
+ "version": "2.1.0",
4
4
  "scripts": {
5
5
  "build": "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types && yarn build:types:downlevel'",
6
- "build:cjs": "yarn g:tsc -p tsconfig.cjs.json",
6
+ "build:cjs": "node ../../scripts/inline middleware-retry",
7
7
  "build:es": "yarn g:tsc -p tsconfig.es.json",
8
8
  "build:types": "yarn g:tsc -p tsconfig.types.json",
9
9
  "build:types:downlevel": "downlevel-dts dist-types dist-types/ts3.4",
@@ -31,18 +31,18 @@
31
31
  },
32
32
  "license": "Apache-2.0",
33
33
  "dependencies": {
34
- "@smithy/node-config-provider": "^2.1.9",
35
- "@smithy/protocol-http": "^3.0.12",
36
- "@smithy/service-error-classification": "^2.0.9",
37
- "@smithy/smithy-client": "^2.2.1",
38
- "@smithy/types": "^2.8.0",
39
- "@smithy/util-middleware": "^2.0.9",
40
- "@smithy/util-retry": "^2.0.9",
34
+ "@smithy/node-config-provider": "^2.2.0",
35
+ "@smithy/protocol-http": "^3.1.0",
36
+ "@smithy/service-error-classification": "^2.1.0",
37
+ "@smithy/smithy-client": "^2.3.0",
38
+ "@smithy/types": "^2.9.0",
39
+ "@smithy/util-middleware": "^2.1.0",
40
+ "@smithy/util-retry": "^2.1.0",
41
41
  "tslib": "^2.5.0",
42
42
  "uuid": "^8.3.2"
43
43
  },
44
44
  "devDependencies": {
45
- "@smithy/util-test": "^0.1.12",
45
+ "@smithy/util-test": "^0.1.13",
46
46
  "@tsconfig/recommended": "1.0.1",
47
47
  "@types/uuid": "^8.3.0",
48
48
  "concurrently": "7.0.0",