If you always handle exceptions in the same way, you can write a decorator that hardcodes that behavior and handles the retrying logic:
def retry_decorator(base_function):
def new_function(*args, **kwargs): # This allows you to decorate functions without worrying about what arguments they take
for attempt in range(3):
sleep_seconds = attempt ** 2
sleep(sleep_seconds)
try:
return base_function(*args, **kwargs) # base_function is whatever function this decorator is applied to
except Exception as e:
print(e) # Replace this with whatever you want, as long as it's the same for all possible base_functions
return new_function
@retry_decorator # Replaces send_request() with retry_decorator(send_request)()
def send_request(result):
result["response"] = True
If you want to use different exception handling logic for the different connections, things get a bit more complicated:
def retry_decorator_2(exception_handle_function):
def new_decorator(base_function):
def new_function(*args, **kwargs):
for attempt in range(3):
sleep_seconds = attempt ** 2
sleep(sleep_seconds)
try:
return base_function(*args, **kwargs)
except Exception as e:
exception_handle_function(e)
return new_function
return new_decorator
@retry_decorator_2(print) # Replace 'print' with an exception handling function
def send_request(result):
result["response"] = True
In this case, retry_decorator_2(print) creates a new decorator (which stores print as the exception_handle_function), then applies that decorator to the send_request function.
If you need the exception_handle_function to take arguments, you can pass them as part of the decorator:
def retry_decorator_3(exception_handle_function, *exception_function_args, **exception_function_kwargs):
def new_decorator(base_function):
def new_function(*args, **kwargs):
for attempt in range(3):
sleep_seconds = attempt
sleep(sleep_seconds)
try:
return base_function(*args, **kwargs)
except Exception as e:
exception_handle_function(e, *exception_function_args, **exception_function_kwargs)
return new_function
return new_decorator
@retry_decorator_3(print, 1, 2, 3) # 1, 2, 3 become arguments for the print function, or whatever you replace it with
def send_request(result):
result["response"] = True
resultbe adictinstead of a list, i.e.result = {}instead ofresult = []?