diff --git a/.changeset/orange-goats-hope.md b/.changeset/orange-goats-hope.md new file mode 100644 index 0000000000..937c0c5434 --- /dev/null +++ b/.changeset/orange-goats-hope.md @@ -0,0 +1,5 @@ +--- +'@module-federation/retry-plugin': minor +--- + +Allow fallback function to receive the failed URL in order to build the fallback URL. diff --git a/apps/website-new/docs/en/plugin/plugins/retry-plugin.mdx b/apps/website-new/docs/en/plugin/plugins/retry-plugin.mdx index 4de1c238b5..9e03a9af0a 100644 --- a/apps/website-new/docs/en/plugin/plugins/retry-plugin.mdx +++ b/apps/website-new/docs/en/plugin/plugins/retry-plugin.mdx @@ -96,7 +96,9 @@ type FetchWithRetryOptions = { options?: RequestInit; retryTimes?: number; retryDelay?: number; - fallback?: (() => string) | ((url: string | URL | globalThis.Request) => string); + fallback?: + | (() => string) + | ((url: string | URL | globalThis.Request) => string); } type ScriptWithRetryOptions = { diff --git a/packages/retry-plugin/__tests__/retry.spec.ts b/packages/retry-plugin/__tests__/retry.spec.ts index 126c33459e..f638331527 100644 --- a/packages/retry-plugin/__tests__/retry.spec.ts +++ b/packages/retry-plugin/__tests__/retry.spec.ts @@ -118,6 +118,24 @@ describe('fetchWithRetry', () => { expect(fetch).toHaveBeenLastCalledWith('https://fallback.com', {}); }); + it('should build fallback URL from remote after retries fail', async () => { + mockErrorFetch(); + const retryTimes = 3; + const responsePromise = fetchWithRetry({ + url: 'https://example.com', + retryTimes, + retryDelay: 0, + fallback: (url) => `${url}/fallback`, + }); + vi.advanceTimersByTime(2000 * retryTimes); + + await expect(responsePromise).rejects.toThrow( + 'The request failed three times and has now been abandoned', + ); + expect(fetch).toHaveBeenCalledTimes(5); //first fetch + retryTimes fetch + expect(fetch).toHaveBeenLastCalledWith('https://example.com/fallback', {}); + }); + it('should handle JSON parse error', async () => { const mockFetch = vi.fn().mockResolvedValueOnce({ ok: true,