@@ -369,6 +369,59 @@ describe('set', () => {
369369 `The blob store is unavailable because it's missing required configuration properties` ,
370370 )
371371 } )
372+
373+ test ( 'Retries failed operations' , async ( ) => {
374+ let attempts = 0
375+
376+ const fetcher = async ( ...args : Parameters < typeof globalThis . fetch > ) => {
377+ const [ url , options ] = args
378+ const headers = options ?. headers as Record < string , string >
379+
380+ expect ( options ?. method ) . toBe ( 'put' )
381+
382+ if ( url === `https://api.netlify.com/api/v1/sites/${ siteID } /blobs/${ key } ?context=production` ) {
383+ const data = JSON . stringify ( { url : signedURL } )
384+
385+ expect ( headers . authorization ) . toBe ( `Bearer ${ apiToken } ` )
386+
387+ return new Response ( data )
388+ }
389+
390+ if ( url === signedURL ) {
391+ attempts += 1
392+
393+ expect ( options ?. body ) . toBe ( value )
394+
395+ if ( attempts === 1 ) {
396+ return new Response ( null , { status : 500 } )
397+ }
398+
399+ if ( attempts === 2 ) {
400+ throw new Error ( 'Some network problem' )
401+ }
402+
403+ if ( attempts === 3 ) {
404+ return new Response ( null , { headers : { 'X-RateLimit-Reset' : '10' } , status : 429 } )
405+ }
406+
407+ return new Response ( value )
408+ }
409+
410+ throw new Error ( `Unexpected fetch call: ${ url } ` )
411+ }
412+
413+ const blobs = new Blobs ( {
414+ authentication : {
415+ token : apiToken ,
416+ } ,
417+ fetcher,
418+ siteID,
419+ } )
420+
421+ await blobs . set ( key , value )
422+
423+ expect ( attempts ) . toBe ( 4 )
424+ } )
372425} )
373426
374427describe ( 'setJSON' , ( ) => {
0 commit comments