|
3 | 3 |
|
4 | 4 | import logging |
5 | 5 | import re |
6 | | -from typing import Any, Callable, Iterable, Optional, Pattern, Tuple |
| 6 | +from typing import Any, Callable, Iterable, Optional, Pattern, Tuple, cast |
7 | 7 |
|
8 | 8 | import tenacity |
9 | 9 | from tenacity import after_log, retry_if_exception, stop_after_attempt, wait_exponential |
@@ -172,12 +172,18 @@ def retry_api_call( |
172 | 172 | Only retries on AWS exceptions listed in the RetryConfig.exceptions. |
173 | 173 | Does not retry on client errors or non-AWS exceptions. |
174 | 174 | """ |
| 175 | + |
| 176 | + def _extract_code(ex: BaseException) -> Optional[str]: |
| 177 | + resp = cast(Optional[dict[str, Any]], getattr(ex, "response", None)) |
| 178 | + err = cast(Optional[dict[str, Any]], (resp or {}).get("Error")) |
| 179 | + return cast(Optional[str], (err or {}).get("Code")) |
| 180 | + |
| 181 | + def _is_retryable(ex: BaseException) -> bool: |
| 182 | + code = _extract_code(ex) |
| 183 | + return code is not None and code in config.exceptions |
| 184 | + |
175 | 185 | retry = tenacity.Retrying( |
176 | | - retry=retry_if_exception( |
177 | | - lambda e: getattr(e, "response", {}).get("Error", {}).get("Code") in config.exceptions |
178 | | - if e |
179 | | - else False |
180 | | - ), |
| 186 | + retry=retry_if_exception(_is_retryable), |
181 | 187 | stop=stop_after_attempt(config.attempt), |
182 | 188 | wait=wait_exponential( |
183 | 189 | multiplier=config.multiplier, |
|
0 commit comments