Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@aws-sdk/middleware-retry

Package Overview
Dependencies
Maintainers
5
Versions
151
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aws-sdk/middleware-retry - npm Package Compare versions

Comparing version 3.185.0 to 3.186.0

8

CHANGELOG.md

@@ -6,2 +6,10 @@ # Change Log

# [3.186.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.185.0...v3.186.0) (2022-10-06)
**Note:** Version bump only for package @aws-sdk/middleware-retry
# [3.185.0](https://github.com/aws/aws-sdk-js-v3/compare/v3.184.0...v3.185.0) (2022-10-05)

@@ -8,0 +16,0 @@

45

dist-es/AdaptiveRetryStrategy.js

@@ -0,21 +1,34 @@

import { __awaiter, __extends, __generator, __rest } from "tslib";
import { RETRY_MODES } from "./config";
import { DefaultRateLimiter } from "./DefaultRateLimiter";
import { StandardRetryStrategy } from "./StandardRetryStrategy";
export class AdaptiveRetryStrategy extends StandardRetryStrategy {
constructor(maxAttemptsProvider, options) {
const { rateLimiter, ...superOptions } = options ?? {};
super(maxAttemptsProvider, superOptions);
this.rateLimiter = rateLimiter ?? new DefaultRateLimiter();
this.mode = RETRY_MODES.ADAPTIVE;
var AdaptiveRetryStrategy = (function (_super) {
__extends(AdaptiveRetryStrategy, _super);
function AdaptiveRetryStrategy(maxAttemptsProvider, options) {
var _this = this;
var _a = options !== null && options !== void 0 ? options : {}, rateLimiter = _a.rateLimiter, superOptions = __rest(_a, ["rateLimiter"]);
_this = _super.call(this, maxAttemptsProvider, superOptions) || this;
_this.rateLimiter = rateLimiter !== null && rateLimiter !== void 0 ? rateLimiter : new DefaultRateLimiter();
_this.mode = RETRY_MODES.ADAPTIVE;
return _this;
}
async retry(next, args) {
return super.retry(next, args, {
beforeRequest: async () => {
return this.rateLimiter.getSendToken();
},
afterRequest: (response) => {
this.rateLimiter.updateClientSendingRate(response);
},
AdaptiveRetryStrategy.prototype.retry = function (next, args) {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
return [2, _super.prototype.retry.call(this, next, args, {
beforeRequest: function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2, this.rateLimiter.getSendToken()];
});
}); },
afterRequest: function (response) {
_this.rateLimiter.updateClientSendingRate(response);
},
})];
});
});
}
}
};
return AdaptiveRetryStrategy;
}(StandardRetryStrategy));
export { AdaptiveRetryStrategy };

@@ -6,3 +6,3 @@ export var RETRY_MODES;

})(RETRY_MODES || (RETRY_MODES = {}));
export const DEFAULT_MAX_ATTEMPTS = 3;
export const DEFAULT_RETRY_MODE = RETRY_MODES.STANDARD;
export var DEFAULT_MAX_ATTEMPTS = 3;
export var DEFAULT_RETRY_MODE = RETRY_MODES.STANDARD;

@@ -0,1 +1,2 @@

import { __assign, __awaiter, __generator } from "tslib";
import { normalizeProvider } from "@aws-sdk/util-middleware";

@@ -5,22 +6,22 @@ import { AdaptiveRetryStrategy } from "./AdaptiveRetryStrategy";

import { StandardRetryStrategy } from "./StandardRetryStrategy";
export const ENV_MAX_ATTEMPTS = "AWS_MAX_ATTEMPTS";
export const CONFIG_MAX_ATTEMPTS = "max_attempts";
export const NODE_MAX_ATTEMPT_CONFIG_OPTIONS = {
environmentVariableSelector: (env) => {
const value = env[ENV_MAX_ATTEMPTS];
export var ENV_MAX_ATTEMPTS = "AWS_MAX_ATTEMPTS";
export var CONFIG_MAX_ATTEMPTS = "max_attempts";
export var NODE_MAX_ATTEMPT_CONFIG_OPTIONS = {
environmentVariableSelector: function (env) {
var value = env[ENV_MAX_ATTEMPTS];
if (!value)
return undefined;
const maxAttempt = parseInt(value);
var maxAttempt = parseInt(value);
if (Number.isNaN(maxAttempt)) {
throw new Error(`Environment variable ${ENV_MAX_ATTEMPTS} mast be a number, got "${value}"`);
throw new Error("Environment variable ".concat(ENV_MAX_ATTEMPTS, " mast be a number, got \"").concat(value, "\""));
}
return maxAttempt;
},
configFileSelector: (profile) => {
const value = profile[CONFIG_MAX_ATTEMPTS];
configFileSelector: function (profile) {
var value = profile[CONFIG_MAX_ATTEMPTS];
if (!value)
return undefined;
const maxAttempt = parseInt(value);
var maxAttempt = parseInt(value);
if (Number.isNaN(maxAttempt)) {
throw new Error(`Shared config file entry ${CONFIG_MAX_ATTEMPTS} mast be a number, got "${value}"`);
throw new Error("Shared config file entry ".concat(CONFIG_MAX_ATTEMPTS, " mast be a number, got \"").concat(value, "\""));
}

@@ -31,25 +32,30 @@ return maxAttempt;

};
export const resolveRetryConfig = (input) => {
const maxAttempts = normalizeProvider(input.maxAttempts ?? DEFAULT_MAX_ATTEMPTS);
return {
...input,
maxAttempts,
retryStrategy: async () => {
if (input.retryStrategy) {
return input.retryStrategy;
}
const retryMode = await normalizeProvider(input.retryMode)();
if (retryMode === RETRY_MODES.ADAPTIVE) {
return new AdaptiveRetryStrategy(maxAttempts);
}
return new StandardRetryStrategy(maxAttempts);
},
};
export var resolveRetryConfig = function (input) {
var _a;
var maxAttempts = normalizeProvider((_a = input.maxAttempts) !== null && _a !== void 0 ? _a : DEFAULT_MAX_ATTEMPTS);
return __assign(__assign({}, input), { maxAttempts: maxAttempts, retryStrategy: function () { return __awaiter(void 0, void 0, void 0, function () {
var retryMode;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (input.retryStrategy) {
return [2, input.retryStrategy];
}
return [4, normalizeProvider(input.retryMode)()];
case 1:
retryMode = _a.sent();
if (retryMode === RETRY_MODES.ADAPTIVE) {
return [2, new AdaptiveRetryStrategy(maxAttempts)];
}
return [2, new StandardRetryStrategy(maxAttempts)];
}
});
}); } });
};
export const ENV_RETRY_MODE = "AWS_RETRY_MODE";
export const CONFIG_RETRY_MODE = "retry_mode";
export const NODE_RETRY_MODE_CONFIG_OPTIONS = {
environmentVariableSelector: (env) => env[ENV_RETRY_MODE],
configFileSelector: (profile) => profile[CONFIG_RETRY_MODE],
export var ENV_RETRY_MODE = "AWS_RETRY_MODE";
export var CONFIG_RETRY_MODE = "retry_mode";
export var NODE_RETRY_MODE_CONFIG_OPTIONS = {
environmentVariableSelector: function (env) { return env[ENV_RETRY_MODE]; },
configFileSelector: function (profile) { return profile[CONFIG_RETRY_MODE]; },
default: DEFAULT_RETRY_MODE,
};

@@ -1,9 +0,9 @@

export const DEFAULT_RETRY_DELAY_BASE = 100;
export const MAXIMUM_RETRY_DELAY = 20 * 1000;
export const THROTTLING_RETRY_DELAY_BASE = 500;
export const INITIAL_RETRY_TOKENS = 500;
export const RETRY_COST = 5;
export const TIMEOUT_RETRY_COST = 10;
export const NO_RETRY_INCREMENT = 1;
export const INVOCATION_ID_HEADER = "amz-sdk-invocation-id";
export const REQUEST_HEADER = "amz-sdk-request";
export var DEFAULT_RETRY_DELAY_BASE = 100;
export var MAXIMUM_RETRY_DELAY = 20 * 1000;
export var THROTTLING_RETRY_DELAY_BASE = 500;
export var INITIAL_RETRY_TOKENS = 500;
export var RETRY_COST = 5;
export var TIMEOUT_RETRY_COST = 10;
export var NO_RETRY_INCREMENT = 1;
export var INVOCATION_ID_HEADER = "amz-sdk-invocation-id";
export var REQUEST_HEADER = "amz-sdk-request";

@@ -0,4 +1,6 @@

import { __awaiter, __generator } from "tslib";
import { isThrottlingError } from "@aws-sdk/service-error-classification";
export class DefaultRateLimiter {
constructor(options) {
var DefaultRateLimiter = (function () {
function DefaultRateLimiter(options) {
var _a, _b, _c, _d, _e;
this.currentCapacity = 0;

@@ -11,8 +13,8 @@ this.enabled = false;

this.timeWindow = 0;
this.beta = options?.beta ?? 0.7;
this.minCapacity = options?.minCapacity ?? 1;
this.minFillRate = options?.minFillRate ?? 0.5;
this.scaleConstant = options?.scaleConstant ?? 0.4;
this.smooth = options?.smooth ?? 0.8;
const currentTimeInSeconds = this.getCurrentTimeInSeconds();
this.beta = (_a = options === null || options === void 0 ? void 0 : options.beta) !== null && _a !== void 0 ? _a : 0.7;
this.minCapacity = (_b = options === null || options === void 0 ? void 0 : options.minCapacity) !== null && _b !== void 0 ? _b : 1;
this.minFillRate = (_c = options === null || options === void 0 ? void 0 : options.minFillRate) !== null && _c !== void 0 ? _c : 0.5;
this.scaleConstant = (_d = options === null || options === void 0 ? void 0 : options.scaleConstant) !== null && _d !== void 0 ? _d : 0.4;
this.smooth = (_e = options === null || options === void 0 ? void 0 : options.smooth) !== null && _e !== void 0 ? _e : 0.8;
var currentTimeInSeconds = this.getCurrentTimeInSeconds();
this.lastThrottleTime = currentTimeInSeconds;

@@ -23,21 +25,37 @@ this.lastTxRateBucket = Math.floor(this.getCurrentTimeInSeconds());

}
getCurrentTimeInSeconds() {
DefaultRateLimiter.prototype.getCurrentTimeInSeconds = function () {
return Date.now() / 1000;
}
async getSendToken() {
return this.acquireTokenBucket(1);
}
async acquireTokenBucket(amount) {
if (!this.enabled) {
return;
}
this.refillTokenBucket();
if (amount > this.currentCapacity) {
const delay = ((amount - this.currentCapacity) / this.fillRate) * 1000;
await new Promise((resolve) => setTimeout(resolve, delay));
}
this.currentCapacity = this.currentCapacity - amount;
}
refillTokenBucket() {
const timestamp = this.getCurrentTimeInSeconds();
};
DefaultRateLimiter.prototype.getSendToken = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2, this.acquireTokenBucket(1)];
});
});
};
DefaultRateLimiter.prototype.acquireTokenBucket = function (amount) {
return __awaiter(this, void 0, void 0, function () {
var delay_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.enabled) {
return [2];
}
this.refillTokenBucket();
if (!(amount > this.currentCapacity)) return [3, 2];
delay_1 = ((amount - this.currentCapacity) / this.fillRate) * 1000;
return [4, new Promise(function (resolve) { return setTimeout(resolve, delay_1); })];
case 1:
_a.sent();
_a.label = 2;
case 2:
this.currentCapacity = this.currentCapacity - amount;
return [2];
}
});
});
};
DefaultRateLimiter.prototype.refillTokenBucket = function () {
var timestamp = this.getCurrentTimeInSeconds();
if (!this.lastTimestamp) {

@@ -47,11 +65,11 @@ this.lastTimestamp = timestamp;

}
const fillAmount = (timestamp - this.lastTimestamp) * this.fillRate;
var fillAmount = (timestamp - this.lastTimestamp) * this.fillRate;
this.currentCapacity = Math.min(this.maxCapacity, this.currentCapacity + fillAmount);
this.lastTimestamp = timestamp;
}
updateClientSendingRate(response) {
let calculatedRate;
};
DefaultRateLimiter.prototype.updateClientSendingRate = function (response) {
var calculatedRate;
this.updateMeasuredRate();
if (isThrottlingError(response)) {
const rateToUse = !this.enabled ? this.measuredTxRate : Math.min(this.measuredTxRate, this.fillRate);
var rateToUse = !this.enabled ? this.measuredTxRate : Math.min(this.measuredTxRate, this.fillRate);
this.lastMaxRate = rateToUse;

@@ -67,18 +85,18 @@ this.calculateTimeWindow();

}
const newRate = Math.min(calculatedRate, 2 * this.measuredTxRate);
var newRate = Math.min(calculatedRate, 2 * this.measuredTxRate);
this.updateTokenBucketRate(newRate);
}
calculateTimeWindow() {
};
DefaultRateLimiter.prototype.calculateTimeWindow = function () {
this.timeWindow = this.getPrecise(Math.pow((this.lastMaxRate * (1 - this.beta)) / this.scaleConstant, 1 / 3));
}
cubicThrottle(rateToUse) {
};
DefaultRateLimiter.prototype.cubicThrottle = function (rateToUse) {
return this.getPrecise(rateToUse * this.beta);
}
cubicSuccess(timestamp) {
};
DefaultRateLimiter.prototype.cubicSuccess = function (timestamp) {
return this.getPrecise(this.scaleConstant * Math.pow(timestamp - this.lastThrottleTime - this.timeWindow, 3) + this.lastMaxRate);
}
enableTokenBucket() {
};
DefaultRateLimiter.prototype.enableTokenBucket = function () {
this.enabled = true;
}
updateTokenBucketRate(newRate) {
};
DefaultRateLimiter.prototype.updateTokenBucketRate = function (newRate) {
this.refillTokenBucket();

@@ -88,9 +106,9 @@ this.fillRate = Math.max(newRate, this.minFillRate);

this.currentCapacity = Math.min(this.currentCapacity, this.maxCapacity);
}
updateMeasuredRate() {
const t = this.getCurrentTimeInSeconds();
const timeBucket = Math.floor(t * 2) / 2;
};
DefaultRateLimiter.prototype.updateMeasuredRate = function () {
var t = this.getCurrentTimeInSeconds();
var timeBucket = Math.floor(t * 2) / 2;
this.requestCount++;
if (timeBucket > this.lastTxRateBucket) {
const currentRate = this.requestCount / (timeBucket - this.lastTxRateBucket);
var currentRate = this.requestCount / (timeBucket - this.lastTxRateBucket);
this.measuredTxRate = this.getPrecise(currentRate * this.smooth + this.measuredTxRate * (1 - this.smooth));

@@ -100,6 +118,8 @@ this.requestCount = 0;

}
}
getPrecise(num) {
};
DefaultRateLimiter.prototype.getPrecise = function (num) {
return parseFloat(num.toFixed(8));
}
}
};
return DefaultRateLimiter;
}());
export { DefaultRateLimiter };
import { NO_RETRY_INCREMENT, RETRY_COST, TIMEOUT_RETRY_COST } from "./constants";
export const getDefaultRetryQuota = (initialRetryTokens, options) => {
const MAX_CAPACITY = initialRetryTokens;
const noRetryIncrement = options?.noRetryIncrement ?? NO_RETRY_INCREMENT;
const retryCost = options?.retryCost ?? RETRY_COST;
const timeoutRetryCost = options?.timeoutRetryCost ?? TIMEOUT_RETRY_COST;
let availableCapacity = initialRetryTokens;
const getCapacityAmount = (error) => (error.name === "TimeoutError" ? timeoutRetryCost : retryCost);
const hasRetryTokens = (error) => getCapacityAmount(error) <= availableCapacity;
const retrieveRetryTokens = (error) => {
export var getDefaultRetryQuota = function (initialRetryTokens, options) {
var _a, _b, _c;
var MAX_CAPACITY = initialRetryTokens;
var noRetryIncrement = (_a = options === null || options === void 0 ? void 0 : options.noRetryIncrement) !== null && _a !== void 0 ? _a : NO_RETRY_INCREMENT;
var retryCost = (_b = options === null || options === void 0 ? void 0 : options.retryCost) !== null && _b !== void 0 ? _b : RETRY_COST;
var timeoutRetryCost = (_c = options === null || options === void 0 ? void 0 : options.timeoutRetryCost) !== null && _c !== void 0 ? _c : TIMEOUT_RETRY_COST;
var availableCapacity = initialRetryTokens;
var getCapacityAmount = function (error) { return (error.name === "TimeoutError" ? timeoutRetryCost : retryCost); };
var hasRetryTokens = function (error) { return getCapacityAmount(error) <= availableCapacity; };
var retrieveRetryTokens = function (error) {
if (!hasRetryTokens(error)) {
throw new Error("No retry token available");
}
const capacityAmount = getCapacityAmount(error);
var capacityAmount = getCapacityAmount(error);
availableCapacity -= capacityAmount;
return capacityAmount;
};
const releaseRetryTokens = (capacityReleaseAmount) => {
availableCapacity += capacityReleaseAmount ?? noRetryIncrement;
var releaseRetryTokens = function (capacityReleaseAmount) {
availableCapacity += capacityReleaseAmount !== null && capacityReleaseAmount !== void 0 ? capacityReleaseAmount : noRetryIncrement;
availableCapacity = Math.min(availableCapacity, MAX_CAPACITY);
};
return Object.freeze({
hasRetryTokens,
retrieveRetryTokens,
releaseRetryTokens,
hasRetryTokens: hasRetryTokens,
retrieveRetryTokens: retrieveRetryTokens,
releaseRetryTokens: releaseRetryTokens,
});
};
import { MAXIMUM_RETRY_DELAY } from "./constants";
export const defaultDelayDecider = (delayBase, attempts) => Math.floor(Math.min(MAXIMUM_RETRY_DELAY, Math.random() * 2 ** attempts * delayBase));
export var defaultDelayDecider = function (delayBase, attempts) {
return Math.floor(Math.min(MAXIMUM_RETRY_DELAY, Math.random() * Math.pow(2, attempts) * delayBase));
};

@@ -0,12 +1,20 @@

import { __awaiter, __generator } from "tslib";
import { HttpRequest } from "@aws-sdk/protocol-http";
import { INVOCATION_ID_HEADER, REQUEST_HEADER } from "./constants";
export const omitRetryHeadersMiddleware = () => (next) => async (args) => {
const { request } = args;
if (HttpRequest.isInstance(request)) {
delete request.headers[INVOCATION_ID_HEADER];
delete request.headers[REQUEST_HEADER];
}
return next(args);
export var omitRetryHeadersMiddleware = function () {
return function (next) {
return function (args) { return __awaiter(void 0, void 0, void 0, function () {
var request;
return __generator(this, function (_a) {
request = args.request;
if (HttpRequest.isInstance(request)) {
delete request.headers[INVOCATION_ID_HEADER];
delete request.headers[REQUEST_HEADER];
}
return [2, next(args)];
});
}); };
};
};
export const omitRetryHeadersMiddlewareOptions = {
export var omitRetryHeadersMiddlewareOptions = {
name: "omitRetryHeadersMiddleware",

@@ -18,6 +26,6 @@ tags: ["RETRY", "HEADERS", "OMIT_RETRY_HEADERS"],

};
export const getOmitRetryHeadersPlugin = (options) => ({
applyToStack: (clientStack) => {
export var getOmitRetryHeadersPlugin = function (options) { return ({
applyToStack: function (clientStack) {
clientStack.addRelativeTo(omitRetryHeadersMiddleware(), omitRetryHeadersMiddlewareOptions);
},
});
}); };
import { isClockSkewError, isRetryableByTrait, isThrottlingError, isTransientError, } from "@aws-sdk/service-error-classification";
export const defaultRetryDecider = (error) => {
export var defaultRetryDecider = function (error) {
if (!error) {

@@ -4,0 +4,0 @@ return false;

@@ -1,8 +0,20 @@

export const retryMiddleware = (options) => (next, context) => async (args) => {
const retryStrategy = await options.retryStrategy();
if (retryStrategy?.mode)
context.userAgent = [...(context.userAgent || []), ["cfg/retry-mode", retryStrategy.mode]];
return retryStrategy.retry(next, args);
import { __awaiter, __generator, __read, __spreadArray } from "tslib";
export var retryMiddleware = function (options) {
return function (next, context) {
return function (args) { return __awaiter(void 0, void 0, void 0, function () {
var retryStrategy;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, options.retryStrategy()];
case 1:
retryStrategy = _a.sent();
if (retryStrategy === null || retryStrategy === void 0 ? void 0 : retryStrategy.mode)
context.userAgent = __spreadArray(__spreadArray([], __read((context.userAgent || [])), false), [["cfg/retry-mode", retryStrategy.mode]], false);
return [2, retryStrategy.retry(next, args)];
}
});
}); };
};
};
export const retryMiddlewareOptions = {
export var retryMiddlewareOptions = {
name: "retryMiddleware",

@@ -14,6 +26,6 @@ tags: ["RETRY"],

};
export const getRetryPlugin = (options) => ({
applyToStack: (clientStack) => {
export var getRetryPlugin = function (options) { return ({
applyToStack: function (clientStack) {
clientStack.add(retryMiddleware(options), retryMiddlewareOptions);
},
});
}); };

@@ -0,1 +1,2 @@

import { __awaiter, __generator } from "tslib";
import { HttpRequest, HttpResponse } from "@aws-sdk/protocol-http";

@@ -9,85 +10,130 @@ import { isThrottlingError } from "@aws-sdk/service-error-classification";

import { defaultRetryDecider } from "./retryDecider";
export class StandardRetryStrategy {
constructor(maxAttemptsProvider, options) {
var StandardRetryStrategy = (function () {
function StandardRetryStrategy(maxAttemptsProvider, options) {
var _a, _b, _c;
this.maxAttemptsProvider = maxAttemptsProvider;
this.mode = RETRY_MODES.STANDARD;
this.retryDecider = options?.retryDecider ?? defaultRetryDecider;
this.delayDecider = options?.delayDecider ?? defaultDelayDecider;
this.retryQuota = options?.retryQuota ?? getDefaultRetryQuota(INITIAL_RETRY_TOKENS);
this.retryDecider = (_a = options === null || options === void 0 ? void 0 : options.retryDecider) !== null && _a !== void 0 ? _a : defaultRetryDecider;
this.delayDecider = (_b = options === null || options === void 0 ? void 0 : options.delayDecider) !== null && _b !== void 0 ? _b : defaultDelayDecider;
this.retryQuota = (_c = options === null || options === void 0 ? void 0 : options.retryQuota) !== null && _c !== void 0 ? _c : getDefaultRetryQuota(INITIAL_RETRY_TOKENS);
}
shouldRetry(error, attempts, maxAttempts) {
StandardRetryStrategy.prototype.shouldRetry = function (error, attempts, maxAttempts) {
return attempts < maxAttempts && this.retryDecider(error) && this.retryQuota.hasRetryTokens(error);
}
async getMaxAttempts() {
let maxAttempts;
try {
maxAttempts = await this.maxAttemptsProvider();
}
catch (error) {
maxAttempts = DEFAULT_MAX_ATTEMPTS;
}
return maxAttempts;
}
async retry(next, args, options) {
let retryTokenAmount;
let attempts = 0;
let totalDelay = 0;
const maxAttempts = await this.getMaxAttempts();
const { request } = args;
if (HttpRequest.isInstance(request)) {
request.headers[INVOCATION_ID_HEADER] = v4();
}
while (true) {
try {
if (HttpRequest.isInstance(request)) {
request.headers[REQUEST_HEADER] = `attempt=${attempts + 1}; max=${maxAttempts}`;
};
StandardRetryStrategy.prototype.getMaxAttempts = function () {
return __awaiter(this, void 0, void 0, function () {
var maxAttempts, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, this.maxAttemptsProvider()];
case 1:
maxAttempts = _a.sent();
return [3, 3];
case 2:
error_1 = _a.sent();
maxAttempts = DEFAULT_MAX_ATTEMPTS;
return [3, 3];
case 3: return [2, maxAttempts];
}
if (options?.beforeRequest) {
await options.beforeRequest();
});
});
};
StandardRetryStrategy.prototype.retry = function (next, args, options) {
return __awaiter(this, void 0, void 0, function () {
var retryTokenAmount, attempts, totalDelay, maxAttempts, request, _loop_1, this_1, state_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
attempts = 0;
totalDelay = 0;
return [4, this.getMaxAttempts()];
case 1:
maxAttempts = _a.sent();
request = args.request;
if (HttpRequest.isInstance(request)) {
request.headers[INVOCATION_ID_HEADER] = v4();
}
_loop_1 = function () {
var _b, response, output, e_1, err, delayFromDecider, delayFromResponse, delay_1;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_c.trys.push([0, 4, , 7]);
if (HttpRequest.isInstance(request)) {
request.headers[REQUEST_HEADER] = "attempt=".concat(attempts + 1, "; max=").concat(maxAttempts);
}
if (!(options === null || options === void 0 ? void 0 : options.beforeRequest)) return [3, 2];
return [4, options.beforeRequest()];
case 1:
_c.sent();
_c.label = 2;
case 2: return [4, next(args)];
case 3:
_b = _c.sent(), response = _b.response, output = _b.output;
if (options === null || options === void 0 ? void 0 : options.afterRequest) {
options.afterRequest(response);
}
this_1.retryQuota.releaseRetryTokens(retryTokenAmount);
output.$metadata.attempts = attempts + 1;
output.$metadata.totalRetryDelay = totalDelay;
return [2, { value: { response: response, output: output } }];
case 4:
e_1 = _c.sent();
err = asSdkError(e_1);
attempts++;
if (!this_1.shouldRetry(err, attempts, maxAttempts)) return [3, 6];
retryTokenAmount = this_1.retryQuota.retrieveRetryTokens(err);
delayFromDecider = this_1.delayDecider(isThrottlingError(err) ? THROTTLING_RETRY_DELAY_BASE : DEFAULT_RETRY_DELAY_BASE, attempts);
delayFromResponse = getDelayFromRetryAfterHeader(err.$response);
delay_1 = Math.max(delayFromResponse || 0, delayFromDecider);
totalDelay += delay_1;
return [4, new Promise(function (resolve) { return setTimeout(resolve, delay_1); })];
case 5:
_c.sent();
return [2, "continue"];
case 6:
if (!err.$metadata) {
err.$metadata = {};
}
err.$metadata.attempts = attempts;
err.$metadata.totalRetryDelay = totalDelay;
throw err;
case 7: return [2];
}
});
};
this_1 = this;
_a.label = 2;
case 2:
if (!true) return [3, 4];
return [5, _loop_1()];
case 3:
state_1 = _a.sent();
if (typeof state_1 === "object")
return [2, state_1.value];
return [3, 2];
case 4: return [2];
}
const { response, output } = await next(args);
if (options?.afterRequest) {
options.afterRequest(response);
}
this.retryQuota.releaseRetryTokens(retryTokenAmount);
output.$metadata.attempts = attempts + 1;
output.$metadata.totalRetryDelay = totalDelay;
return { response, output };
}
catch (e) {
const err = asSdkError(e);
attempts++;
if (this.shouldRetry(err, attempts, maxAttempts)) {
retryTokenAmount = this.retryQuota.retrieveRetryTokens(err);
const delayFromDecider = this.delayDecider(isThrottlingError(err) ? THROTTLING_RETRY_DELAY_BASE : DEFAULT_RETRY_DELAY_BASE, attempts);
const delayFromResponse = getDelayFromRetryAfterHeader(err.$response);
const delay = Math.max(delayFromResponse || 0, delayFromDecider);
totalDelay += delay;
await new Promise((resolve) => setTimeout(resolve, delay));
continue;
}
if (!err.$metadata) {
err.$metadata = {};
}
err.$metadata.attempts = attempts;
err.$metadata.totalRetryDelay = totalDelay;
throw err;
}
}
}
}
const getDelayFromRetryAfterHeader = (response) => {
});
});
};
return StandardRetryStrategy;
}());
export { StandardRetryStrategy };
var getDelayFromRetryAfterHeader = function (response) {
if (!HttpResponse.isInstance(response))
return;
const retryAfterHeaderName = Object.keys(response.headers).find((key) => key.toLowerCase() === "retry-after");
var retryAfterHeaderName = Object.keys(response.headers).find(function (key) { return key.toLowerCase() === "retry-after"; });
if (!retryAfterHeaderName)
return;
const retryAfter = response.headers[retryAfterHeaderName];
const retryAfterSeconds = Number(retryAfter);
var retryAfter = response.headers[retryAfterHeaderName];
var retryAfterSeconds = Number(retryAfter);
if (!Number.isNaN(retryAfterSeconds))
return retryAfterSeconds * 1000;
const retryAfterDate = new Date(retryAfter);
var retryAfterDate = new Date(retryAfter);
return retryAfterDate.getTime() - Date.now();
};
const asSdkError = (error) => {
var asSdkError = function (error) {
if (error instanceof Error)

@@ -99,3 +145,3 @@ return error;

return new Error(error);
return new Error(`AWS SDK error wrapper for ${error}`);
return new Error("AWS SDK error wrapper for ".concat(error));
};
{
"name": "@aws-sdk/middleware-retry",
"version": "3.185.0",
"version": "3.186.0",
"scripts": {

@@ -23,6 +23,6 @@ "build": "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types'",

"dependencies": {
"@aws-sdk/protocol-http": "3.183.0",
"@aws-sdk/service-error-classification": "3.185.0",
"@aws-sdk/types": "3.183.0",
"@aws-sdk/util-middleware": "3.183.0",
"@aws-sdk/protocol-http": "3.186.0",
"@aws-sdk/service-error-classification": "3.186.0",
"@aws-sdk/types": "3.186.0",
"@aws-sdk/util-middleware": "3.186.0",
"tslib": "^2.3.1",

@@ -32,3 +32,3 @@ "uuid": "^8.3.2"

"devDependencies": {
"@aws-sdk/node-config-provider": "3.183.0",
"@aws-sdk/node-config-provider": "3.186.0",
"@tsconfig/recommended": "1.0.1",

@@ -35,0 +35,0 @@ "@types/uuid": "^8.3.0",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc