-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(shared): introduce retryable and throwable to fetch-utils (#2921)
- Loading branch information
Showing
12 changed files
with
156 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
"qiankun": patch | ||
"@qiankunjs/shared": patch | ||
--- | ||
|
||
feat(shared): introduce retryable and throwable to fetch-utils |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
packages/shared/src/fetch-utils/__tests__/makeFetchRetryable.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// @vitest-environment edge-runtime | ||
import { expect, it, vi } from 'vitest'; | ||
import { makeFetchRetryable } from '../makeFetchRetryable'; | ||
|
||
const slogan = 'Hello Qiankun 3.0'; | ||
|
||
it('should retry automatically while fetch throw error', async () => { | ||
const retryTimes = 3; | ||
let count = 0; | ||
const fetch = vi.fn(() => { | ||
if (count < retryTimes) { | ||
count++; | ||
throw new Error('network error'); | ||
} | ||
return Promise.resolve(new Response(slogan, { status: 201 })); | ||
}); | ||
const wrappedFetch = makeFetchRetryable(fetch, retryTimes); | ||
const url = 'https://success.qiankun.org'; | ||
const res = await wrappedFetch(url); | ||
expect(res.status).toBe(201); | ||
expect(fetch).toHaveBeenCalledTimes(4); | ||
}); | ||
|
||
it('should work well while response status is 200', async () => { | ||
const fetch = vi.fn(() => { | ||
return Promise.resolve(new Response(slogan, { status: 200 })); | ||
}); | ||
const wrappedFetch = makeFetchRetryable(fetch); | ||
const url = 'https://success.qiankun.org'; | ||
const res = await wrappedFetch(url); | ||
expect(res.status).toBe(200); | ||
expect(fetch).toHaveBeenCalledTimes(1); | ||
}); |
31 changes: 31 additions & 0 deletions
31
packages/shared/src/fetch-utils/__tests__/makeFetchThrowable.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/** | ||
* @author Kuitos | ||
* @since 2024-03-05 | ||
*/ | ||
import { expect, it, vi } from 'vitest'; | ||
import { makeFetchThrowable } from '../makeFetchThrowable'; | ||
|
||
const slogan = 'Hello Qiankun 3.0'; | ||
|
||
it('should throw error while response status is not 200~400', async () => { | ||
const fetch = vi.fn(() => { | ||
return Promise.resolve(new Response(slogan, { status: 400 })); | ||
}); | ||
const wrappedFetch = makeFetchThrowable(fetch); | ||
const url = 'https://success.qiankun.org'; | ||
try { | ||
await wrappedFetch(url); | ||
} catch (e) { | ||
expect((e as unknown as Error).message).include('RESPONSE_ERROR_AS_STATUS_INVALID'); | ||
} | ||
}); | ||
|
||
it('should work well while response status is 200', async () => { | ||
const fetch = vi.fn(() => { | ||
return Promise.resolve(new Response(slogan, { status: 200 })); | ||
}); | ||
const wrappedFetch = makeFetchThrowable(fetch); | ||
const url = 'https://success.qiankun.org'; | ||
const res = await wrappedFetch(url); | ||
expect(res.status).toBe(200); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* @author Kuitos | ||
* @since 2024-03-05 | ||
*/ | ||
|
||
import { type Fetch } from './utils'; | ||
|
||
export const makeFetchRetryable: (fetch: Fetch, retryTimes?: number) => Fetch = (fetch, retryTimes = 1) => { | ||
let retryCount = 0; | ||
|
||
const fetchWithRetryable: Fetch = async (input, init) => { | ||
try { | ||
return await fetch(input, init); | ||
} catch (e) { | ||
if (retryCount < retryTimes) { | ||
retryCount++; | ||
|
||
if (process.env.NODE_ENV === 'development') { | ||
console.debug( | ||
`[qiankun] fetch retrying --> url: ${ | ||
typeof input === 'string' ? input : 'url' in input ? input.url : input.href | ||
} , time: ${retryCount}`, | ||
); | ||
} | ||
|
||
return await fetchWithRetryable(input, init); | ||
} | ||
|
||
throw e; | ||
} | ||
}; | ||
|
||
return fetchWithRetryable; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* @author Kuitos | ||
* @since 2024-03-05 | ||
* wrap fetch to throw error when response status is not 200~400 | ||
*/ | ||
|
||
import { type Fetch, isValidResponse } from './utils'; | ||
|
||
export const makeFetchThrowable: (fetch: Fetch) => Fetch = (fetch) => { | ||
return async (url, init) => { | ||
const res = await fetch(url, init); | ||
if (!isValidResponse(res.status)) { | ||
throw new Error( | ||
`[RESPONSE_ERROR_AS_STATUS_INVALID] ${res.status} ${res.statusText} ${ | ||
typeof url === 'string' ? url : 'url' in url ? url.url : url.href | ||
} ${JSON.stringify(init)}`, | ||
); | ||
} | ||
|
||
return res; | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export type Fetch = typeof window.fetch; | ||
|
||
export const isValidResponse = (status: number): boolean => { | ||
return status >= 200 && status < 400; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters