Execute an operation that might fail and returns its result, or raise the exception that was thrown depending on the `Backoff` object. `do`: the operation to call. Expects no argument. `fail`: the failure handler, expects the last error that was thrown ``is_r
(
self,
do: Callable[[], Awaitable[T]],
fail: Union[
Callable[[Exception], Any],
Callable[[Exception, int], Any],
],
is_retryable: Optional[Callable[[Exception], bool]] = None,
with_failure_count: bool = False,
)
| 45 | ) |
| 46 | |
| 47 | async def call_with_retry( |
| 48 | self, |
| 49 | do: Callable[[], Awaitable[T]], |
| 50 | fail: Union[ |
| 51 | Callable[[Exception], Any], |
| 52 | Callable[[Exception, int], Any], |
| 53 | ], |
| 54 | is_retryable: Optional[Callable[[Exception], bool]] = None, |
| 55 | with_failure_count: bool = False, |
| 56 | ) -> T: |
| 57 | """ |
| 58 | Execute an operation that might fail and returns its result, or |
| 59 | raise the exception that was thrown depending on the `Backoff` object. |
| 60 | `do`: the operation to call. Expects no argument. |
| 61 | `fail`: the failure handler, expects the last error that was thrown |
| 62 | ``is_retryable``: optional function to determine if an error is retryable |
| 63 | ``with_failure_count``: if True, the failure count is passed to the failure handler |
| 64 | """ |
| 65 | self._backoff.reset() |
| 66 | failures = 0 |
| 67 | while True: |
| 68 | try: |
| 69 | return await do() |
| 70 | except self._supported_errors as error: |
| 71 | if is_retryable and not is_retryable(error): |
| 72 | raise |
| 73 | failures += 1 |
| 74 | |
| 75 | if with_failure_count: |
| 76 | await fail(error, failures) |
| 77 | else: |
| 78 | await fail(error) |
| 79 | |
| 80 | if self._retries >= 0 and failures > self._retries: |
| 81 | raise error |
| 82 | backoff = self._backoff.compute(failures) |
| 83 | if backoff > 0: |
| 84 | await sleep(backoff) |
no test coverage detected