Skip to content

Commit 283574b

Browse files
authored
feat(retry-plugin): allow fallback function to receive failed URL (#3145)
1 parent d1e0f3e commit 283574b

File tree

5 files changed

+31
-5
lines changed

5 files changed

+31
-5
lines changed

.changeset/violet-fans-sleep.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@module-federation/retry-plugin': patch
3+
'website-new': patch
4+
---
5+
6+
feat(retry-plugin): allow fallback function to receive failed URL

apps/website-new/docs/en/plugin/plugins/retry-plugin.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ type FetchWithRetryOptions = {
9696
options?: RequestInit;
9797
retryTimes?: number;
9898
retryDelay?: number;
99-
fallback?: () => string;
99+
fallback?: (() => string) | ((url: string | URL | globalThis.Request) => string);
100100
}
101101

102102
type ScriptWithRetryOptions = {
@@ -143,9 +143,9 @@ type ScriptWithRetryOptions = {
143143
- The delay time between each retry (in milliseconds).
144144

145145
- **fallback**:
146-
- `() => string`
146+
- `() => string | ((url: string | URL | globalThis.Request) => string)`
147147
- optional
148-
- Returns the URL of a backup resource after all retries fail.
148+
- A function, which can optionally receive the failed URL, that returns a fallback string to be used if all retries fail. This function is called when all retry attempts have failed.
149149

150150
### ScriptWithRetryOptions 类型说明
151151

packages/retry-plugin/__tests__/retry.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,22 @@ describe('fetchWithRetry', () => {
136136
}),
137137
).rejects.toThrow('Json parse error');
138138
});
139+
140+
it('should build fallback URL from remote after retries fail', async () => {
141+
mockErrorFetch();
142+
const retryTimes = 3;
143+
const responsePromise = fetchWithRetry({
144+
url: 'https://example.com',
145+
retryTimes,
146+
retryDelay: 0,
147+
fallback: (url) => `${url}/fallback`,
148+
});
149+
vi.advanceTimersByTime(2000 * retryTimes);
150+
151+
await expect(responsePromise).rejects.toThrow(
152+
'The request failed three times and has now been abandoned',
153+
);
154+
expect(fetch).toHaveBeenCalledTimes(5); //first fetch + retryTimes fetch
155+
expect(fetch).toHaveBeenLastCalledWith('https://example.com/fallback', {});
156+
});
139157
});

packages/retry-plugin/src/fetch-retry.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ async function fetchWithRetry({
3737
);
3838
if (fallback && typeof fallback === 'function') {
3939
return fetchWithRetry({
40-
url: fallback(),
40+
url: fallback(url),
4141
options,
4242
retryTimes: 0,
4343
retryDelay: 0,

packages/retry-plugin/src/types.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ export interface FetchWithRetryOptions {
33
options?: RequestInit;
44
retryTimes?: number;
55
retryDelay?: number;
6-
fallback?: () => string;
6+
fallback?:
7+
| (() => string)
8+
| ((url: string | URL | globalThis.Request) => string);
79
}
810

911
export interface ScriptWithRetryOptions {

0 commit comments

Comments
 (0)