From 54f3b6860a8e81b11c705bf0cbe05eeb8728e668 Mon Sep 17 00:00:00 2001 From: "Kai (Tam Nhu) Tran" <61256810+kaitranntt@users.noreply.github.com> Date: Sat, 30 May 2026 14:54:54 -0400 Subject: [PATCH] fix: tolerate null retryable check --- src/utils/__tests__/retry-strategy.test.ts | 20 ++++++++++++++++++++ src/utils/retry-strategy.ts | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/utils/__tests__/retry-strategy.test.ts b/src/utils/__tests__/retry-strategy.test.ts index ad398b81..1e24bc34 100644 --- a/src/utils/__tests__/retry-strategy.test.ts +++ b/src/utils/__tests__/retry-strategy.test.ts @@ -25,6 +25,26 @@ describe('withRetry', () => { expect(fn).toHaveBeenCalledTimes(3); }); + it('uses the default retryability check when retryableCheck is null at runtime', async () => { + let attempt = 0; + const fn = mock(() => { + attempt++; + if (attempt < 2) { + return Promise.reject(new RetryableError('transient failure')); + } + return Promise.resolve('ok'); + }); + + const result = await withRetry(fn, { + maxRetries: 3, + baseDelayMs: 1, + retryableCheck: null, + } as unknown as RetryOptions); + + expect(result).toBe('ok'); + expect(fn).toHaveBeenCalledTimes(2); + }); + it('throws after max retries exhausted', async () => { const fn = mock(() => Promise.reject(new RetryableError('always fails'))); await expect(withRetry(fn, { maxRetries: 2, baseDelayMs: 1 })).rejects.toThrow('always fails'); diff --git a/src/utils/retry-strategy.ts b/src/utils/retry-strategy.ts index 33ebeee3..50489b6b 100644 --- a/src/utils/retry-strategy.ts +++ b/src/utils/retry-strategy.ts @@ -99,7 +99,7 @@ export async function withRetry(fn: () => Promise, options: RetryOptions): throw new Error('withRetry: baseDelayMs must be >= 0'); } - const isRetryable = retryableCheck; + const isRetryable = retryableCheck ?? defaultRetryableCheck; let lastError: unknown; for (let attempt = 0; attempt <= maxRetries; attempt++) {