| 54 | |
| 55 | |
| 56 | def _is_rate_limit_error(exc: BaseException | None) -> bool: |
| 57 | current: BaseException | None = exc |
| 58 | while current is not None: |
| 59 | status_code = getattr(current, "status_code", None) |
| 60 | if status_code == 429: |
| 61 | return True |
| 62 | response = getattr(current, "response", None) |
| 63 | if getattr(response, "status_code", None) == 429: |
| 64 | return True |
| 65 | text = str(current).lower() |
| 66 | if "rate limit" in text or "ratelimit" in text or "too many requests" in text: |
| 67 | return True |
| 68 | current = current.__cause__ if isinstance(current.__cause__, BaseException) else None |
| 69 | return False |
| 70 | |
| 71 | |
| 72 | def _is_transient_http_error(exc: BaseException | None) -> bool: |