@@ -306,25 +306,55 @@ export const RETRYABLE_ERR_FN_DEFAULT = function (err?: GaxiosError) {
306306 if ( ! err || ! err . config ) return false ;
307307
308308 const method = ( err . config . method || 'GET' ) . toUpperCase ( ) ;
309+ const url = err . config . url || '' ;
309310 const params = err . config . params || { } ;
310311
312+ const status = err . response ?. status ;
313+ if ( status && [ 401 , 405 , 412 ] . includes ( status ) ) return false ;
314+
311315 const hasPrecondition = ! ! (
312316 params . ifGenerationMatch !== undefined ||
313317 params . ifMetagenerationMatch !== undefined ||
314318 params . ifSourceGenerationMatch !== undefined
315319 ) ;
316320
317- const isIdempotent =
318- [ 'GET' , 'HEAD' , 'OPTIONS' , 'TRACE' ] . includes ( method ) || ! ! hasPrecondition ;
321+ const isGet = method === 'GET' ;
322+ const isHead = method === 'HEAD' ;
323+ const isPut = method === 'PUT' ;
324+ const isDelete = method === 'DELETE' ;
325+ const isPost = method === 'POST' ;
326+
327+ let isIdempotent = false ;
328+ if ( isGet || isHead ) {
329+ isIdempotent = true ;
330+ } else if ( hasPrecondition ) {
331+ isIdempotent = true ;
332+ } else if ( isDelete ) {
333+ if ( ! url . toString ( ) . includes ( '/o/' ) ) {
334+ isIdempotent = true ;
335+ }
336+ } else if ( isPut ) {
337+ const isSpecialMutation =
338+ url . toString ( ) . includes ( '/iam' ) || url . toString ( ) . includes ( '/hmacKeys/' ) ;
339+ if ( ! isSpecialMutation ) {
340+ isIdempotent = true ;
341+ }
342+ } else if ( isPost ) {
343+ if ( url . toString ( ) . includes ( '/o' ) || url . toString ( ) . includes ( '/v1/b' ) ) {
344+ isIdempotent = true ;
345+ }
346+ }
319347 if ( ! isIdempotent ) return false ;
320348
321349 const isConnectionProblem = ( reason : string ) => {
322350 return (
323- reason . includes ( 'eai_again' ) || // DNS lookup error
351+ reason . includes ( 'eai_again' ) ||
324352 reason === 'econnreset' ||
325353 reason === 'unexpected connection closure' ||
326354 reason === 'epipe' ||
327- reason === 'socket connection timeout'
355+ reason === 'socket connection timeout' ||
356+ reason === 'econnrefused' ||
357+ reason === 'etimedout'
328358 ) ;
329359 } ;
330360
@@ -349,6 +379,14 @@ export const RETRYABLE_ERR_FN_DEFAULT = function (err?: GaxiosError) {
349379 return true ;
350380 }
351381 }
382+
383+ const message = ( err . message || '' ) . toLowerCase ( ) ;
384+ if (
385+ message . includes ( 'unexpected end of json input' ) ||
386+ message . includes ( 'the operation was aborted' )
387+ ) {
388+ return true ;
389+ }
352390 }
353391 return false ;
354392} ;
0 commit comments