UNPKG

7.3 kBJavaScriptView Raw
1import { __awaiter, __generator } from "tslib";
2import { HttpRequest } from "@aws-sdk/protocol-http";
3import { isThrottlingError } from "@aws-sdk/service-error-classification";
4import { v4 } from "uuid";
5import { DEFAULT_MAX_ATTEMPTS, RETRY_MODES } from "./config";
6import { DEFAULT_RETRY_DELAY_BASE, INITIAL_RETRY_TOKENS, INVOCATION_ID_HEADER, REQUEST_HEADER, THROTTLING_RETRY_DELAY_BASE, } from "./constants";
7import { getDefaultRetryQuota } from "./defaultRetryQuota";
8import { defaultDelayDecider } from "./delayDecider";
9import { defaultRetryDecider } from "./retryDecider";
10var StandardRetryStrategy = (function () {
11 function StandardRetryStrategy(maxAttemptsProvider, options) {
12 var _a, _b, _c;
13 this.maxAttemptsProvider = maxAttemptsProvider;
14 this.mode = RETRY_MODES.STANDARD;
15 this.retryDecider = (_a = options === null || options === void 0 ? void 0 : options.retryDecider) !== null && _a !== void 0 ? _a : defaultRetryDecider;
16 this.delayDecider = (_b = options === null || options === void 0 ? void 0 : options.delayDecider) !== null && _b !== void 0 ? _b : defaultDelayDecider;
17 this.retryQuota = (_c = options === null || options === void 0 ? void 0 : options.retryQuota) !== null && _c !== void 0 ? _c : getDefaultRetryQuota(INITIAL_RETRY_TOKENS);
18 }
19 StandardRetryStrategy.prototype.shouldRetry = function (error, attempts, maxAttempts) {
20 return attempts < maxAttempts && this.retryDecider(error) && this.retryQuota.hasRetryTokens(error);
21 };
22 StandardRetryStrategy.prototype.getMaxAttempts = function () {
23 return __awaiter(this, void 0, void 0, function () {
24 var maxAttempts, error_1;
25 return __generator(this, function (_a) {
26 switch (_a.label) {
27 case 0:
28 _a.trys.push([0, 2, , 3]);
29 return [4, this.maxAttemptsProvider()];
30 case 1:
31 maxAttempts = _a.sent();
32 return [3, 3];
33 case 2:
34 error_1 = _a.sent();
35 maxAttempts = DEFAULT_MAX_ATTEMPTS;
36 return [3, 3];
37 case 3: return [2, maxAttempts];
38 }
39 });
40 });
41 };
42 StandardRetryStrategy.prototype.retry = function (next, args, options) {
43 return __awaiter(this, void 0, void 0, function () {
44 var retryTokenAmount, attempts, totalDelay, maxAttempts, request, _loop_1, this_1, state_1;
45 return __generator(this, function (_a) {
46 switch (_a.label) {
47 case 0:
48 attempts = 0;
49 totalDelay = 0;
50 return [4, this.getMaxAttempts()];
51 case 1:
52 maxAttempts = _a.sent();
53 request = args.request;
54 if (HttpRequest.isInstance(request)) {
55 request.headers[INVOCATION_ID_HEADER] = v4();
56 }
57 _loop_1 = function () {
58 var _b, response, output, e_1, err, delay_1;
59 return __generator(this, function (_c) {
60 switch (_c.label) {
61 case 0:
62 _c.trys.push([0, 4, , 7]);
63 if (HttpRequest.isInstance(request)) {
64 request.headers[REQUEST_HEADER] = "attempt=".concat(attempts + 1, "; max=").concat(maxAttempts);
65 }
66 if (!(options === null || options === void 0 ? void 0 : options.beforeRequest)) return [3, 2];
67 return [4, options.beforeRequest()];
68 case 1:
69 _c.sent();
70 _c.label = 2;
71 case 2: return [4, next(args)];
72 case 3:
73 _b = _c.sent(), response = _b.response, output = _b.output;
74 if (options === null || options === void 0 ? void 0 : options.afterRequest) {
75 options.afterRequest(response);
76 }
77 this_1.retryQuota.releaseRetryTokens(retryTokenAmount);
78 output.$metadata.attempts = attempts + 1;
79 output.$metadata.totalRetryDelay = totalDelay;
80 return [2, { value: { response: response, output: output } }];
81 case 4:
82 e_1 = _c.sent();
83 err = asSdkError(e_1);
84 attempts++;
85 if (!this_1.shouldRetry(err, attempts, maxAttempts)) return [3, 6];
86 retryTokenAmount = this_1.retryQuota.retrieveRetryTokens(err);
87 delay_1 = this_1.delayDecider(isThrottlingError(err) ? THROTTLING_RETRY_DELAY_BASE : DEFAULT_RETRY_DELAY_BASE, attempts);
88 totalDelay += delay_1;
89 return [4, new Promise(function (resolve) { return setTimeout(resolve, delay_1); })];
90 case 5:
91 _c.sent();
92 return [2, "continue"];
93 case 6:
94 if (!err.$metadata) {
95 err.$metadata = {};
96 }
97 err.$metadata.attempts = attempts;
98 err.$metadata.totalRetryDelay = totalDelay;
99 throw err;
100 case 7: return [2];
101 }
102 });
103 };
104 this_1 = this;
105 _a.label = 2;
106 case 2:
107 if (!true) return [3, 4];
108 return [5, _loop_1()];
109 case 3:
110 state_1 = _a.sent();
111 if (typeof state_1 === "object")
112 return [2, state_1.value];
113 return [3, 2];
114 case 4: return [2];
115 }
116 });
117 });
118 };
119 return StandardRetryStrategy;
120}());
121export { StandardRetryStrategy };
122var asSdkError = function (error) {
123 if (error instanceof Error)
124 return error;
125 if (error instanceof Object)
126 return Object.assign(new Error(), error);
127 if (typeof error === "string")
128 return new Error(error);
129 return new Error("AWS SDK error wrapper for ".concat(error));
130};