0

I tried to implement the exponential backoff for my function using the reference code in Implementing a retry routine

However in my case I do not want my function to fail or throw an error after the set number of retries. I would want to catch the error and log it and continue with the rest of the code. Tried multiple things but did not work for me. If someone could assist that would be great. Below is the the sample code. Also please make comments if I'm not handling the other custom exception correctly.

import random, time
from functools import wraps 

class ThrottledException(Exception):
    pass

def retry(ExceptionToCheck, retries=5, delay=1, backoff=2, logger=None):
    """Retry calling the decorated function using an exponential backoff.
    """

    def deco_retry(f):

        @wraps(f)
        def f_retry(*args, **kwargs):
            _tries, _delay = retries, delay

            while _tries >= 1:
                try:
                    return f(*args, **kwargs)
                except ExceptionToCheck:
                    msg = f"{ExceptionToCheck}, Retrying in {_delay} seconds"
                    if logger:
                        #logger.exception(msg) # would print stack trace
                        logger.warning(msg)
                    else:
                        print(msg)

                    time.sleep(_delay)
                    _tries -= 1
                    _delay *= backoff
            return f(*args, **kwargs)

        return f_retry  # true decorator

    return deco_retry 

@retry(ThrottledException, retries=1, delay=1,backoff=2)            
def testfunction(param1, param2, param3):
    try:
        #response = requests.request("POST", url, headers=headers, data=payload)
        rnd = random.random()
        print(rnd)
        if rnd < 0.5:
            response = "Too Many Requests"
            raise ThrottledException
        else: 
            response = {"response":"created"}
        
        return response

    except ThrottledException as e:
        raise ThrottledException
    except Exception as e:
        print("Generic Exception")

res = testfunction('test',{'test1':'test1'}, {'test2':'test2'})
print(res)
Tim Roberts
  • 48,973
  • 4
  • 21
  • 30
thedataguy
  • 11
  • 4

1 Answers1

0

Can you try the following instead?

def exponential_retry(max_retries: int, initial_delay: float = 1.0, multiplier: float = 2.0):
    def decorator_retry(func):
        def wrapper_retry(self, *args, **kwargs):
            retries = 0
            delay = initial_delay
            while retries < max_retries:
                try:
                    return func(self, *args, **kwargs)
                except requests.RequestException as e:
                    log.warning(f"API call failed: {e}")
                    retries += 1
                    if retries < max_retries:
                        log.info(f"Retrying in {delay} seconds...")
                        time.sleep(delay)
                        delay *= multiplier
                    else:
                        log.error("Exceeded maximum number of retries.")
                        raise Exception("Exceeded maximum number of retries.") from e

        return wrapper_retry

    return decorator_retry