浏览代码

Chore: add timeout on speedtest API fetching

SukkaW 2 年之前
父节点
当前提交
d83f8ccd04
共有 2 个文件被更改,包括 26 次插入12 次删除
  1. 7 3
      Build/build-speedtest-domainset.ts
  2. 19 9
      Build/lib/fetch-retry.ts

+ 7 - 3
Build/build-speedtest-domainset.ts

@@ -13,7 +13,7 @@ import { getGorhillPublicSuffixPromise } from './lib/get-gorhill-publicsuffix';
 const s = new Sema(3);
 
 const latestTopUserAgentsPromise = fetchWithRetry('https://unpkg.com/top-user-agents@latest/index.json')
-  .then(res => res.json() as Promise<string[]>);
+  .then(res => res.json<string[]>());
 
 const querySpeedtestApi = async (keyword: string): Promise<Array<string | null>> => {
   const topUserAgents = (await Promise.all([
@@ -39,13 +39,17 @@ const querySpeedtestApi = async (keyword: string): Promise<Array<string | null>>
         'Sec-Fetch-Mode': 'cors',
         'Sec-Fetch-Site': 'same-origin',
         'Sec-Gpc': '1'
-      }
+      },
+      retry: {
+        retryOnAborted: true
+      },
+      signal: AbortSignal.timeout(4000)
     });
     if (!res.ok) {
       throw new Error(`${res.statusText}\n${await res.text()}`);
     }
 
-    const json = await res.json() as Array<{ url: string }>;
+    const json = await res.json<Array<{ url: string }>>();
 
     s.release();
 

+ 19 - 9
Build/lib/fetch-retry.ts

@@ -42,11 +42,16 @@ interface FetchRetryOpt {
   factor?: number,
   maxRetryAfter?: number,
   retry?: number,
-  onRetry?: (err: Error) => void
+  onRetry?: (err: Error) => void,
+  retryOnAborted?: boolean
 }
 
-function createFetchRetry($fetch: typeof fetch): typeof fetch {
-  const fetchRetry = async (url: string | URL, opts: RequestInit & { retry?: FetchRetryOpt } = {}) => {
+interface FetchWithRetry {
+  (url: string | URL | Request, opts?: RequestInit & { retry?: FetchRetryOpt }): Promise<Response>
+}
+
+function createFetchRetry($fetch: typeof fetch): FetchWithRetry {
+  const fetchRetry: FetchWithRetry = async (url, opts = {}) => {
     const retryOpts = Object.assign(
       {
         // timeouts will be [10, 60, 360, 2160, 12960]
@@ -54,13 +59,14 @@ function createFetchRetry($fetch: typeof fetch): typeof fetch {
         minTimeout: MIN_TIMEOUT,
         retries: MAX_RETRIES,
         factor: FACTOR,
-        maxRetryAfter: MAX_RETRY_AFTER
+        maxRetryAfter: MAX_RETRY_AFTER,
+        retryOnAborted: false
       },
       opts.retry
     );
 
     try {
-      return await retry(async (bail) => {
+      return await retry<Response>(async (bail) => {
         try {
           // this will be retried
           const res = (await $fetch(url, opts)) as Response;
@@ -87,13 +93,17 @@ function createFetchRetry($fetch: typeof fetch): typeof fetch {
               err.name === 'AbortError'
               || ('digest' in err && err.digest === 'AbortError')
             ) {
-              console.log(picocolors.gray('[fetch abort]'), picocolors.gray(url.toString()));
-              return bail(err);
+              if (!retryOpts.retryOnAborted) {
+                console.log(picocolors.gray('[fetch abort]'), url);
+                return bail(err) as never;
+              }
             }
           }
           if (isClientError(err)) {
-            return bail(err);
+            return bail(err) as never;
           }
+
+          console.log(picocolors.gray('[fetch fail]'), url);
           throw err;
         }
       }, retryOpts);
@@ -110,7 +120,7 @@ function createFetchRetry($fetch: typeof fetch): typeof fetch {
     fetchRetry[key] = $fetch[key];
   }
 
-  return fetchRetry as typeof fetch;
+  return fetchRetry;
 }
 
 export const defaultRequestInit: RequestInit = {