Transient failures worth auto-retrying: any transport/connection error (no * usable HTTP status — socket reset, DNS, timeout, TLS drop) plus 5xx/408/429 * server responses. Real 4xx client errors (auth, bad request) are not retried.
(error: unknown)
| 33 | * usable HTTP status — socket reset, DNS, timeout, TLS drop) plus 5xx/408/429 |
| 34 | * server responses. Real 4xx client errors (auth, bad request) are not retried. */ |
| 35 | function isRetryableStreamError(error: unknown): boolean { |
| 36 | const err = error as { status?: number; code?: number | string } |
| 37 | const status = Number(err?.status ?? err?.code) |
| 38 | if (Number.isFinite(status) && status !== 0) { |
| 39 | return status >= 500 || status === 408 || status === 429 |
| 40 | } |
| 41 | return true |
| 42 | } |
| 43 | |
| 44 | function retryBackoffMs(attempt: number): number { |
| 45 | return Math.min(500 * 2 ** attempt, 8000) |