diff options
| author | Dax <[email protected]> | 2026-04-15 10:26:20 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-04-15 14:26:20 +0000 |
| commit | be9432a893dd1662c10ff41c7ab552bcba8f3e1b (patch) | |
| tree | f49000b3dd9c3bea5247d319e8fcbd4fb879b7b0 /packages/shared/src/util/retry.ts | |
| parent | af20191d1cd60a7f4a421ad81eca5053f7deace1 (diff) | |
| download | opencode-be9432a893dd1662c10ff41c7ab552bcba8f3e1b.tar.gz opencode-be9432a893dd1662c10ff41c7ab552bcba8f3e1b.zip | |
shared package (#22626)
Diffstat (limited to 'packages/shared/src/util/retry.ts')
| -rw-r--r-- | packages/shared/src/util/retry.ts | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/packages/shared/src/util/retry.ts b/packages/shared/src/util/retry.ts new file mode 100644 index 000000000..0014a604c --- /dev/null +++ b/packages/shared/src/util/retry.ts @@ -0,0 +1,41 @@ +export interface RetryOptions { + attempts?: number + delay?: number + factor?: number + maxDelay?: number + retryIf?: (error: unknown) => boolean +} + +const TRANSIENT_MESSAGES = [ + "load failed", + "network connection was lost", + "network request failed", + "failed to fetch", + "econnreset", + "econnrefused", + "etimedout", + "socket hang up", +] + +function isTransientError(error: unknown): boolean { + if (!error) return false + const message = String(error instanceof Error ? error.message : error).toLowerCase() + return TRANSIENT_MESSAGES.some((m) => message.includes(m)) +} + +export async function retry<T>(fn: () => Promise<T>, options: RetryOptions = {}): Promise<T> { + const { attempts = 3, delay = 500, factor = 2, maxDelay = 10000, retryIf = isTransientError } = options + + let lastError: unknown + for (let attempt = 0; attempt < attempts; attempt++) { + try { + return await fn() + } catch (error) { + lastError = error + if (attempt === attempts - 1 || !retryIf(error)) throw error + const wait = Math.min(delay * Math.pow(factor, attempt), maxDelay) + await new Promise((resolve) => setTimeout(resolve, wait)) + } + } + throw lastError +} |
