Feat/retry fetch notifications (#21813)

This commit is contained in:
Aishanee Shah
2026-03-10 23:33:50 -04:00
committed by GitHub
parent 8b09ccc288
commit f8ad3a200a
24 changed files with 165 additions and 92 deletions

View File

@@ -350,6 +350,25 @@ describe('retryWithBackoff', () => {
expect(mockFn).toHaveBeenCalledTimes(2);
});
it("should retry on 'Incomplete JSON segment' when retryFetchErrors is true", async () => {
const mockFn = vi.fn();
mockFn.mockRejectedValueOnce(
new Error('Incomplete JSON segment at the end'),
);
mockFn.mockResolvedValueOnce('success');
const promise = retryWithBackoff(mockFn, {
retryFetchErrors: true,
initialDelayMs: 10,
});
await vi.runAllTimersAsync();
const result = await promise;
expect(result).toBe('success');
expect(mockFn).toHaveBeenCalledTimes(2);
});
it('should retry on common network error codes (ECONNRESET)', async () => {
const mockFn = vi.fn();
const error = new Error('read ECONNRESET');

View File

@@ -100,6 +100,7 @@ function getNetworkErrorCode(error: unknown): string | undefined {
}
const FETCH_FAILED_MESSAGE = 'fetch failed';
const INCOMPLETE_JSON_MESSAGE = 'incomplete json segment';
/**
* Default predicate function to determine if a retry should be attempted.
@@ -119,8 +120,12 @@ export function isRetryableError(
}
if (retryFetchErrors && error instanceof Error) {
// Check for generic fetch failed message (case-insensitive)
if (error.message.toLowerCase().includes(FETCH_FAILED_MESSAGE)) {
const lowerMessage = error.message.toLowerCase();
// Check for generic fetch failed message or incomplete JSON segment (common stream error)
if (
lowerMessage.includes(FETCH_FAILED_MESSAGE) ||
lowerMessage.includes(INCOMPLETE_JSON_MESSAGE)
) {
return true;
}
}