UNPKG

@snap/camera-kit

Version:
62 lines 3.16 kB
import { __awaiter } from "tslib"; import { copyDefinedProperties } from "../common/copyDefinedProperties"; import { getLogger } from "../logger/logger"; const logger = getLogger("retryingHandler"); const logRetry = (responseOrError, sleep) => { logger.warn(`Retrying handler got failed response:`, responseOrError, `Waited ${sleep} millis, attempting retry now.`); }; const sleep = (millis) => new Promise((resolve) => setTimeout(resolve, millis)); const randomInRange = (min, max) => Math.round(Math.random() * (max - min) + min); const defaultOptions = { backoffMultiple: 3, baseSleep: 500, maxSleep: 5 * 1000, maxRetries: 10, retryPredicate: (responseOrError) => (responseOrError instanceof Response ? !responseOrError.ok : true), }; export function ensureClonedRequest(input) { return input instanceof Request ? input.clone() : input; } export const createRetryingHandler = (options = {}) => { const definedOptions = copyDefinedProperties(options); const { backoffMultiple, baseSleep, maxSleep, maxRetries, retryPredicate } = Object.assign(Object.assign({}, defaultOptions), definedOptions); const jitterSleep = (priorSleep) => __awaiter(void 0, void 0, void 0, function* () { const nextSleep = Math.min(maxSleep, randomInRange(baseSleep, priorSleep * backoffMultiple)); yield sleep(nextSleep); return nextSleep; }); return (next) => (req, metadata) => { const attemptFn = (priorSleep, retryCount) => (() => __awaiter(void 0, void 0, void 0, function* () { var _a, _b; try { const response = yield next(ensureClonedRequest(req), metadata); if (retryCount < maxRetries && retryPredicate(response, retryCount)) { const nextSleep = yield jitterSleep(priorSleep); if ((_a = metadata === null || metadata === void 0 ? void 0 : metadata.signal) === null || _a === void 0 ? void 0 : _a.aborted) return response; logRetry(response, nextSleep); return attemptFn(nextSleep, retryCount + 1); } return response; } catch (error) { if (!(error instanceof Error)) { throw new Error("Invalid type caught by retrying handler. Handlers may only throw Errors. Got " + `${JSON.stringify(error)}`); } if (error.name === "AbortError") throw error; if (retryCount < maxRetries && retryPredicate(error, retryCount)) { const nextSleep = yield jitterSleep(priorSleep); if ((_b = metadata === null || metadata === void 0 ? void 0 : metadata.signal) === null || _b === void 0 ? void 0 : _b.aborted) throw error; logRetry(error, nextSleep); return attemptFn(nextSleep, retryCount + 1); } throw error; } }))(); return attemptFn(baseSleep, 0); }; }; //# sourceMappingURL=retryingHandler.js.map