在Python中实现重试时创建常规异常类

2024-09-28 05:18:31 发布

您现在位置:Python中文网/ 问答频道 /正文

正如标题所解释的,我想创建一个通用异常类,从稍后在其他类中捕获的内置异常类继承

这是我的密码:

from functools import wraps


class ControlledException(TypeError, AttributeError):
    """A generic exception on the program's domain."""


class WithRetry:
    def __init__(self, retries_limit=3, allowed_exceptions=None):
        self.retries_limit = retries_limit
        self.allowed_exceptions = allowed_exceptions or (ControlledException,)

    def __call__(self, operation):
        @wraps(operation)
        def wrapped(*args, **kwargs):
            last_raised = None

            for _ in range(self.retries_limit):
                try:
                    return operation(*args, **kwargs)
                except self.allowed_exceptions as e:
                    print(f'retrying {operation.__qualname__} due to {e}')
                    last_raised = e
            raise last_raised

        return wrapped


@WithRetry()
def test(x):
    x = x + 1
    print(x)


test('a')

ControlledException类继承了我想要捕获的两个异常TypeErrorAttributeError。在这种情况下,程序将捕获TypeError

我不知道为什么参数self.allowed_exceptions对(可控异常,)没有影响。。。 但是,如果我将(ControlledException,)更改为Exception或TypeError,则会捕获错误


Tags: selfdefoperationclassexceptionslastattributeerrorlimit
1条回答
网友
1楼 · 发布于 2024-09-28 05:18:31

当您这样定义自定义异常时,要么直接raise它们,要么捕获原始异常,然后引发自定义异常

在这里,我捕获了原始异常,抑制了它们的回溯,并引发了您的自定义异常

from functools import wraps


class ControlledException(TypeError, AttributeError):
    """A generic exception on the program's domain."""


class WithRetry:
    def __init__(self, retries_limit=3, allowed_exceptions=None):
        self.retries_limit = retries_limit
        self.allowed_exceptions = allowed_exceptions or (ControlledException,)

    def __call__(self, operation):
        @wraps(operation)
        def wrapped(*args, **kwargs):

            for _ in range(self.retries_limit):
                try:
                    return operation(*args, **kwargs)

                # if you want to catch the error, you have to catch the original
                # exceptions as opposed to custom exceptions
                except (TypeError, AttributeError) as exc:
                    print(f"retrying {operation.__qualname__} due to {exc}")

                    # this suppresses the original error message and raises your
                    # custom exception
                    raise ControlledException("Here is your error message!!") from None

        return wrapped


@WithRetry()
def test(x):
    x = x + 1
    print(x)


test("a")

这将打印出:

retrying test due to can only concatenate str (not "int") to str
                                     -
ControlledException                       Traceback (most recent call last)
<ipython-input-364-2a7d6eb73e92> in <module>
     38 
     39 
 -> 40 test('a')

<ipython-input-364-2a7d6eb73e92> in wrapped(*args, **kwargs)
     27                     # this suppresses the original error message and raises your
     28                     # custom exception
 -> 29                     raise ControlledException('Here is your error message!!') from None
     30 
     31         return wrapped

ControlledException: Here is your error message!!

相关问题 更多 >

    热门问题