channable / opnieuw

One weird trick to make your code more reliable
https://tech.channable.com/posts/2020-02-05-opnieuw.html
BSD 3-Clause "New" or "Revised" License
289 stars 11 forks source link

Add support to custom functions instead of exceptions #32

Open iurisilvio opened 10 months ago

iurisilvio commented 10 months ago

I'd like to retry only for some cases of the exception.

Example, I have to retry when SQLAlchemy fails with lock timeout or statement timeout.

I can raise custom exceptions, but it is not useful for anything else.

@retry(...)
def foo():
    try:
        something
    except sqlalchemy.exc.OperationalError as ex:
        if "lock timeout" in ex.orig.diag.message_primary:
            # RETRY
        if "statement timeout" in ex.orig.diag.message_primary:
            # RETRY
        raise

I'd like to extract this logic to make code reusable:

def should_retry(exc):
    return (
        isinstance(exc, sqlalchemy.exc.OperationalError)
        and (
            "lock timeout" in exc.orig.diag.message_primary
            or "statement timeout" in exc.orig.diag.message_primary
        )
    )

@retry(retry_on_exceptions=should_retry)
def foo():
    something

Maybe I can make it per exception:

def should_retry(exc):
    return (
        "lock timeout" in exc.orig.diag.message_primary
        or "statement timeout" in exc.orig.diag.message_primary
    )

@retry(
    retry_on_exceptions=[
        (sqlalchemy.exc.OperationalError, should_retry),
    ],
)
def foo():
    something