@@ -97,10 +97,10 @@ def _should_retry_response(resp_status, content):
9797 if resp_status == _TOO_MANY_REQUESTS :
9898 return True
9999
100- # For 403 errors, we have to check for the `reason` in the response to
100+ # For 403 and 400 errors, we have to check for the `reason` in the response to
101101 # determine if we should retry.
102- if resp_status == http_client .FORBIDDEN :
103- # If there's no details about the 403 type , don't retry.
102+ if resp_status in [ http_client .FORBIDDEN , http_client . BAD_REQUEST ] :
103+ # If there's no details about the error , don't retry.
104104 if not content :
105105 return False
106106
@@ -137,11 +137,16 @@ def _should_retry_response(resp_status, content):
137137 LOGGER .warning ("Invalid JSON content from response: %s" , content )
138138 return False
139139
140- LOGGER .warning ('Encountered 403 Forbidden with reason "%s"' , reason )
141-
142- # Only retry on rate limit related failures.
143- if reason in ("userRateLimitExceeded" , "rateLimitExceeded" ):
144- return True
140+ if resp_status == http_client .FORBIDDEN :
141+ LOGGER .warning ('Encountered 403 Forbidden with reason "%s"' , reason )
142+ # Only retry on rate limit related failures.
143+ if reason in ("userRateLimitExceeded" , "rateLimitExceeded" ):
144+ return True
145+ elif resp_status == http_client .BAD_REQUEST :
146+ LOGGER .warning ('Encountered 400 Bad Request with reason "%s"' , reason )
147+ # Only retry on precondition failures.
148+ if reason in ("failedPrecondition" , "preconditionFailed" ):
149+ return True
145150
146151 # Everything else is a success or non-retriable so break.
147152 return False
0 commit comments