def handler(**kwargs): """ Redo exception handling based on backoff/retry. :return: """ try: return method(**kwargs) except HTTPError as e: logger.error(f'HTTP response code: {e.response.status_code}') logger.exception(e) if e.response.status_code in (429, 503, 504): logger.error(f"Server overloaded: Backing off...") delay = e.response.headers.get("Retry-After", None) if delay: try: raise RetryableError(f"Retry-after: {delay}.", retry_after=int(delay)) except (ValueError, TypeError): pass raise RetryableError(f"Retry exponential backoff.", retry_after=None) raise
def _exponential_backoff(times): ts = datetime.now() logger.info(f"Attempts left: {times['times']}, {ts - times['ts']}") times['delta'] = ts - times['ts'] times['ts'] = ts times['times'] -= 1 raise RetryableError(f"Simulated error...{times['times']}")
def _do_something(test_name, decision_tree): do_error, do_back_off = next(decision_tree) if do_error: logger.debug(f"{test_name}: Raising error with backoff = '{do_back_off}'.") raise RetryableError(f"Error in code block.", retry_after=3 if do_back_off else None) else: logger.debug(f"{test_name}: No error raised.") return 'Completed'
def test_code_block(): """ Example demonstrating using Retrying in a code block. :return: """ try: tries = 3 back_off = 2 for attempt in Retrying(stop=stop_after_attempt(tries), wait=wait_fixed(back_off), reraise=True): with attempt: logger.info(f"Attempts left in block: {tries}") tries -= 1 raise RetryableError(f"Simulated error in code block.", retry_after=10) except RetryableError as e: logger.error(f"Retryable: {e}")
def _stop_after_x_attempts(times): logger.info(f"Attempts left: {times['times']}") times['times'] -= 1 raise RetryableError(f"Simulated error...{times['times']}")
def _flaky_function(message): raise RetryableError(f"Simulated error '{message}'.", retry_after=10)
def _raise_my_exception(): raise RetryableError(f"Simulated error with backoff.", retry_after=10)