@@ -123,7 +123,7 @@ export class FileFetcher {
123123 ) ;
124124 }
125125
126- const response = await fetch ( specifier . toString ( ) ) ;
126+ const response = await fetchWithRetries ( specifier . toString ( ) ) ;
127127 const content = await response . text ( ) ;
128128 const headers : Record < string , string > = { } ;
129129 for ( const [ key , value ] of response . headers ) {
@@ -206,7 +206,7 @@ export class FileFetcher {
206206 requestHeaders . append ( "authorization" , authToken ) ;
207207 }
208208 console . error ( `${ colors . green ( "Download" ) } ${ specifier . toString ( ) } ` ) ;
209- const response = await fetch ( specifier . toString ( ) , {
209+ const response = await fetchWithRetries ( specifier . toString ( ) , {
210210 headers : requestHeaders ,
211211 } ) ;
212212 if ( ! response . ok ) {
@@ -266,3 +266,32 @@ export class FileFetcher {
266266 }
267267 }
268268}
269+
270+ export async function fetchWithRetries (
271+ url : URL | string ,
272+ init ?: { headers ?: Headers } ,
273+ ) {
274+ const maxRetries = 3 ;
275+ let sleepMs = 250 ;
276+ let iterationCount = 0 ;
277+ while ( true ) {
278+ iterationCount ++ ;
279+ try {
280+ const res = await fetch ( url , init ) ;
281+ if ( res . ok || iterationCount > maxRetries ) {
282+ return res ;
283+ }
284+ } catch ( err ) {
285+ if ( iterationCount > maxRetries ) {
286+ throw err ;
287+ }
288+ }
289+ console . warn (
290+ `${
291+ colors . yellow ( "WARN" )
292+ } Failed fetching ${ url } . Retrying in ${ sleepMs } ms...`,
293+ ) ;
294+ await new Promise ( ( resolve ) => setTimeout ( resolve , sleepMs ) ) ;
295+ sleepMs = Math . min ( sleepMs * 2 , 10_000 ) ;
296+ }
297+ }
0 commit comments