Python tenacity: How do I retry a function without raising an exception if all retries fail?

6.1k views Asked by At

let's say I have the following function:

@retry(stop=stop_after_attempt(3))
def foo():
  try:
    response = requests.post(...)
    response.raise_for_status()
    return response
  except Exception as e:
    raise e

This function will retry 3 times, and if all three retries fail, an exception will be raised.

How can I use tenacity to do 3 retries without raising the exception? Something like:

@retry(stop=stop_after_attempt(3))
def foo(ignore_errors=False):
  try:
    response = requests.post(...)
    response.raise_for_status()
    return response
  except Exception as e:
    if ignore_errors and function has been retried three times:
      pass
    raise e
3

There are 3 answers

0
Mooncrater On

Using pure python:

def foo(tries=0,maxTries=3):
    try:
        response = requests.post(...)
        response.raise_for_status()
        return response
    except Exception as e:
        if tries>=maxTries:
            print("Maxtries reached.")
            return
        else:
            foo(tries+1,maxTries)

I'm not sure if a recursive function would help here.

2
b-r-oleary On

The retry decorator has a retry_error_callback argument that can override the default behavior of raising a RetryError if all retries fail. This argument is expected to be a function that accepts one argument, called retry_state, and if you return a value from this function, that value will be returned by the function if all retries fail.

An example:

from tenacity import retry, stop_after_attempt

return_value_on_error = "something"

@retry(
    stop=stop_after_attempt(3),
    retry_error_callback=lambda retry_state: return_value_on_error,
)
def broken_function():
    raise RuntimeError

assert broken_function() == return_value_on_error
0
정도유 On

It's recommended to control exception outside of foo function.

try:
    foo()
except Exception as e:
    print("foo fails with retry: {e}")