UNPKG

@langchain/core

Version:
1 lines 10.4 kB
{"version":3,"file":"index.cjs","names":["isNetworkError"],"sources":["../../../src/utils/p-retry/index.js"],"sourcesContent":["/* oxlint-disable */\nimport isNetworkError from \"../is-network-error/index.js\";\n\nfunction validateRetries(retries) {\n if (typeof retries === \"number\") {\n if (retries < 0) {\n throw new TypeError(\"Expected `retries` to be a non-negative number.\");\n }\n\n if (Number.isNaN(retries)) {\n throw new TypeError(\n \"Expected `retries` to be a valid number or Infinity, got NaN.\"\n );\n }\n } else if (retries !== undefined) {\n throw new TypeError(\"Expected `retries` to be a number or Infinity.\");\n }\n}\n\nfunction validateNumberOption(\n name,\n value,\n { min = 0, allowInfinity = false } = {}\n) {\n if (value === undefined) {\n return;\n }\n\n if (typeof value !== \"number\" || Number.isNaN(value)) {\n throw new TypeError(\n `Expected \\`${name}\\` to be a number${\n allowInfinity ? \" or Infinity\" : \"\"\n }.`\n );\n }\n\n if (!allowInfinity && !Number.isFinite(value)) {\n throw new TypeError(`Expected \\`${name}\\` to be a finite number.`);\n }\n\n if (value < min) {\n throw new TypeError(`Expected \\`${name}\\` to be \\u2265 ${min}.`);\n }\n}\n\nexport class AbortError extends Error {\n constructor(message) {\n super();\n\n if (message instanceof Error) {\n this.originalError = message;\n ({ message } = message);\n } else {\n this.originalError = new Error(message);\n this.originalError.stack = this.stack;\n }\n\n this.name = \"AbortError\";\n this.message = message;\n }\n}\n\nfunction calculateDelay(retriesConsumed, options) {\n const attempt = Math.max(1, retriesConsumed + 1);\n const random = options.randomize ? Math.random() + 1 : 1;\n\n let timeout = Math.round(\n random * options.minTimeout * options.factor ** (attempt - 1)\n );\n timeout = Math.min(timeout, options.maxTimeout);\n\n return timeout;\n}\n\nfunction calculateRemainingTime(start, max) {\n if (!Number.isFinite(max)) {\n return max;\n }\n\n return max - (performance.now() - start);\n}\n\nasync function onAttemptFailure({\n error,\n attemptNumber,\n retriesConsumed,\n startTime,\n options,\n}) {\n const normalizedError =\n error instanceof Error\n ? error\n : new TypeError(\n `Non-error was thrown: \"${error}\". You should only throw errors.`\n );\n\n if (normalizedError instanceof AbortError) {\n throw normalizedError.originalError;\n }\n\n const retriesLeft = Number.isFinite(options.retries)\n ? Math.max(0, options.retries - retriesConsumed)\n : options.retries;\n\n const maxRetryTime = options.maxRetryTime ?? Number.POSITIVE_INFINITY;\n\n const context = Object.freeze({\n error: normalizedError,\n attemptNumber,\n retriesLeft,\n retriesConsumed,\n });\n\n await options.onFailedAttempt(context);\n\n if (calculateRemainingTime(startTime, maxRetryTime) <= 0) {\n throw normalizedError;\n }\n\n const consumeRetry = await options.shouldConsumeRetry(context);\n\n const remainingTime = calculateRemainingTime(startTime, maxRetryTime);\n\n if (remainingTime <= 0 || retriesLeft <= 0) {\n throw normalizedError;\n }\n\n if (\n normalizedError instanceof TypeError &&\n !isNetworkError(normalizedError)\n ) {\n if (consumeRetry) {\n throw normalizedError;\n }\n\n options.signal?.throwIfAborted();\n return false;\n }\n\n if (!(await options.shouldRetry(context))) {\n throw normalizedError;\n }\n\n if (!consumeRetry) {\n options.signal?.throwIfAborted();\n return false;\n }\n\n let delayTime = calculateDelay(retriesConsumed, options);\n const retryAfterMs =\n typeof normalizedError.retryAfterMs === \"number\" &&\n normalizedError.retryAfterMs >= 0\n ? normalizedError.retryAfterMs\n : undefined;\n\n if (retryAfterMs !== undefined) {\n delayTime = Math.max(delayTime, retryAfterMs);\n }\n\n const finalDelay = Math.min(delayTime, remainingTime);\n\n if (finalDelay > 0) {\n await new Promise((resolve, reject) => {\n const onAbort = () => {\n clearTimeout(timeoutToken);\n options.signal?.removeEventListener(\"abort\", onAbort);\n reject(options.signal.reason);\n };\n\n const timeoutToken = setTimeout(() => {\n options.signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, finalDelay);\n\n if (options.unref) {\n timeoutToken.unref?.();\n }\n\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n }\n\n options.signal?.throwIfAborted();\n\n return true;\n}\n\nexport default async function pRetry(input, options = {}) {\n options = { ...options };\n\n validateRetries(options.retries);\n\n if (Object.hasOwn(options, \"forever\")) {\n throw new Error(\n \"The `forever` option is no longer supported. For many use-cases, you can set `retries: Infinity` instead.\"\n );\n }\n\n options.retries ??= 10;\n options.factor ??= 2;\n options.minTimeout ??= 1000;\n options.maxTimeout ??= Number.POSITIVE_INFINITY;\n options.maxRetryTime ??= Number.POSITIVE_INFINITY;\n options.randomize ??= false;\n options.onFailedAttempt ??= () => {};\n options.shouldRetry ??= () => true;\n options.shouldConsumeRetry ??= () => true;\n\n // Validate numeric options and normalize edge cases\n validateNumberOption(\"factor\", options.factor, {\n min: 0,\n allowInfinity: false,\n });\n validateNumberOption(\"minTimeout\", options.minTimeout, {\n min: 0,\n allowInfinity: false,\n });\n validateNumberOption(\"maxTimeout\", options.maxTimeout, {\n min: 0,\n allowInfinity: true,\n });\n validateNumberOption(\"maxRetryTime\", options.maxRetryTime, {\n min: 0,\n allowInfinity: true,\n });\n\n // Treat non-positive factor as 1 to avoid zero backoff or negative behavior\n if (!(options.factor > 0)) {\n options.factor = 1;\n }\n\n options.signal?.throwIfAborted();\n\n let attemptNumber = 0;\n let retriesConsumed = 0;\n const startTime = performance.now();\n\n while (\n Number.isFinite(options.retries) ? retriesConsumed <= options.retries : true\n ) {\n attemptNumber++;\n\n try {\n options.signal?.throwIfAborted();\n\n const result = await input(attemptNumber);\n\n options.signal?.throwIfAborted();\n\n return result;\n } catch (error) {\n if (\n await onAttemptFailure({\n error,\n attemptNumber,\n retriesConsumed,\n startTime,\n options,\n })\n ) {\n retriesConsumed++;\n }\n }\n }\n\n // Should not reach here, but in case it does, throw an error\n throw new Error(\"Retry attempts exhausted without throwing an error.\");\n}\n\nexport function makeRetriable(function_, options) {\n return function (...arguments_) {\n return pRetry(() => function_.apply(this, arguments_), options);\n };\n}\n"],"mappings":"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"}