Python: Exception

 

raise from

try:
    try:
        1 / 0
    except ZeroDivisionError as e:
        raise Exception("with_traceback") from e
except Exception as e:
    print(e, e.__cause__, type(e.__cause__))

try:
    1 / 0
except ZeroDivisionError as e:
    raise Exception("with_traceback") from e

 

 

The bottom exception only has the stacktrace from where we raised our exception. Notice the bottom exception only has the stacktrace where we raised our exception. Your caller could still get the original exception by accessing the __cause__ attribute of the exception they catch.

 

with_traceback

try:
    try:
        1 / 0
    except ZeroDivisionError as e:
        raise Exception("with_traceback").with_traceback(e.__traceback__)
except Exception as e:
    print(e, e.__cause__, type(e.__cause__))

try:
    1 / 0
except ZeroDivisionError as e:
    raise Exception("with_traceback").with_traceback(e.__traceback__)

 

 Using this form, the exception your caller would catch has the trackback from where the original error occurred. Notice the bottom exception has the line where we performed the invalid division as well as the line where we reraise the exception.

Custom Exception

class CloudFirewallError(Exception):
    def __init__(self, message: str):
        super().__init__(f'CloudFirewallError: {message}')


class ApiError(Exception):
    def __init__(self, status_code):
        if status_code == 403:
            message = 'Rate limit reached. Please wait a minute and try again'
        else:
            message = f'HTTP status code: {status_code}'
        super().__init__(message)

 

urllib module

class URLError(OSError):
    def __init__(self, reason, filename=None):
        self.args = reason,
        self.reason = reason
        if filename is not None:
            self.filename = filename

    def __str__(self):
        return '<urlopen error %s>' % self.reason

 

import typing


class HTTPException(Exception):
    def __init__(self, status_code: int, detail: typing.Any = None, headers: dict[str, typing.Any] | None = None):
        if detail is None:
            detail = 'detail'
        self.status_code = status_code
        self.detail = detail
        self.headers = headers

    def __repr__(self) -> str:
        class_name = self.__class__.__name__
        return f'{class_name}(status_code={self.status_code!r}, detail={self.detail!r}'

 

posted @ 2023-03-28 16:10  ascertain  阅读(28)  评论(0编辑  收藏  举报