Retry Decorator with Arguments
Hard · Decorators
A decorator with arguments is a function that returns a decorator: @retry(3) first calls retry(3), and the result decorates the function. So you need three levels: retry(times, on) returns decorator(func), which returns wrapper(*args, **kwargs).
Write retry(times, on=(Exception,)):
- call the function up to times times in total
- if it raises an exception whose type is in on, try again. Any other exception propagates immediately.
- if the last attempt fails too, re-raise that exception
- the wrapper has an attempts attribute: how many attempts the most recent call used (also when it ends with an error)
- keep the function name with functools.wraps
The driver run_retry(times, outcomes) is already written. It decorates a fake fetch() with @retry(times, on=(ConnectionError,)). Each attempt uses the next outcome: "down" raises ConnectionError("server timed out"), "bad" raises ValueError("bad response"), and anything else is returned as the result.