tenacity icon indicating copy to clipboard operation
tenacity copied to clipboard

Access all occurred exceptions in `RetryError`

Open mtvx opened this issue 1 year ago • 2 comments

It would be useful to have access to the exceptions/stacktraces of all attempts, via RetryError.

This would allow to create e.g. metrics out of failed attempts and in general have some logic based on all failures (not only the last).

mtvx avatar Jun 19 '24 07:06 mtvx

I have a way to do this that I was just thinking would be good to contribute upstream. It uses the existing API so it's really just like a wrapper / extension. I'm still looking for the contribution guidelines for this project. I'll check in again during the workweek with more info.

blr246 avatar Jun 22 '24 20:06 blr246

I think this can be achieved using the 'after' callback passed to retrying object.

from tenacity import retry, stop_after_attempt, RetryCallState, Future
import random

outcomes: list[Future] = []
def save_attempt_outcome(outcomes: list):
    def retry(retry_state: RetryCallState):
        outcomes.append((retry_state.outcome, retry_state.outcome_timestamp))
    return retry


def custom_retry(retry_state: RetryCallState):
    return retry_state.outcome.failed or retry_state.outcome.result() == False
        

@retry(stop=stop_after_attempt(10), after=save_attempt_outcome(outcomes), retry=custom_retry)
def raise_my_exception():
    if random.randint(0, 10) > 4:
        return False
    raise Exception("Server Error")

if __name__ == "__main__":
    try:
        raise_my_exception()
    except:
        pass

    for attempt, outcome in enumerate(outcomes):
        print(f"Attempt {attempt} result : {outcome}")

output :

Attempt 0 result : (<Future at 0x788e97404a10 state=finished returned bool>, 5619.904158993)
Attempt 1 result : (<Future at 0x788e975d9960 state=finished returned bool>, 5619.904321571)
Attempt 2 result : (<Future at 0x788e97404c40 state=finished returned bool>, 5619.904444613)
Attempt 3 result : (<Future at 0x788e97404ce0 state=finished returned bool>, 5619.904554819)
Attempt 4 result : (<Future at 0x788e97404ab0 state=finished raised Exception>, 5619.904661261)
Attempt 5 result : (<Future at 0x788e97404ec0 state=finished returned bool>, 5619.904767894)
Attempt 6 result : (<Future at 0x788e97404f60 state=finished returned bool>, 5619.904867902)
Attempt 7 result : (<Future at 0x788e97404e20 state=finished raised Exception>, 5619.904975319)
Attempt 8 result : (<Future at 0x788e97405140 state=finished returned bool>, 5619.905104612)
Attempt 9 result : (<Future at 0x788e974050a0 state=finished raised Exception>, 5619.905205652)

LotfiRafik avatar Mar 13 '25 08:03 LotfiRafik