|
12 | 12 | # See the License for the specific language governing permissions and |
13 | 13 | # limitations under the License. |
14 | 14 |
|
| 15 | +import logging |
| 16 | + |
15 | 17 | from google.api_core import exceptions |
16 | 18 | from google.api_core import retry |
17 | 19 | import google.api_core.future.polling |
18 | 20 | from google.auth import exceptions as auth_exceptions # type: ignore |
19 | 21 | import requests.exceptions |
20 | 22 |
|
| 23 | +_LOGGER = logging.getLogger(__name__) |
21 | 24 |
|
22 | 25 | _RETRYABLE_REASONS = frozenset( |
23 | 26 | ["rateLimitExceeded", "backendError", "internalError", "badGateway"] |
|
61 | 64 | def _should_retry(exc): |
62 | 65 | """Predicate for determining when to retry. |
63 | 66 |
|
64 | | - We retry if and only if the 'reason' is 'backendError' |
65 | | - or 'rateLimitExceeded'. |
| 67 | + We retry if and only if the 'reason' is in _RETRYABLE_REASONS or is |
| 68 | + in _UNSTRUCTURED_RETRYABLE_TYPES. |
66 | 69 | """ |
67 | 70 | try: |
68 | 71 | reason = exc.errors[0]["reason"] |
69 | 72 | except (AttributeError, IndexError, TypeError, KeyError): |
70 | 73 | # Fallback for when errors attribute is missing, empty, or not a dict |
71 | 74 | # or doesn't contain "reason" (e.g. gRPC exceptions). |
| 75 | + _LOGGER.debug("Inspecting unstructured error for retry: %r", exc) |
72 | 76 | return isinstance(exc, _UNSTRUCTURED_RETRYABLE_TYPES) |
73 | 77 |
|
74 | 78 | return reason in _RETRYABLE_REASONS |
|
0 commit comments