首页 > 解决方案 > 具有功能的自定义异常

问题描述

我遇到了一个非常标准的问题,想知道我的解决方案是否正确。

每次发生异常时,我都希望它被调用者捕获并记录,然后重新引发。

因为我不想每次都重复记录消息,所以我创建了一个自定义异常来保存消息数据和日志。

class LoggingException(Exception):
    def __init__(self, message, package_id):
        # Get caller informat
        caller = getframeinfo(stack()[2][0])
        self.filename = caller.filename
        self.function = caller.function

        # Set message info and log
        self.message = message
        if (LogManager.log_handler is None):
            print(message)
        else:
            LogManager.l(package_id, LogLevelEnum.ERROR, message)

用例:

def main_func():
    try:
        secondary_func()
    except Exception as ex:
        raise LoggingException("Some log") from ex

def secondary_func():
    raise LoggingException("Exception info")

问题是我不完全确定有一个异常做任何操作是一个好主意,这是通用的,因为它没有标准的 python 解决方案。

注意:由于产品限制,我没有使用 python 日志记录模块。

标签: pythonpython-3.x

解决方案


试图获取这样的呼叫者信息将是不可靠的。此外,在某些情况下,您感兴趣的不是直接呼叫者。

异常记录本身的想法似乎是明智的。为了妥协,我会将日志记录功能移动到一个单独的方法中,您可以显式地触发它。毕竟,例外大多是常规对象:

class LoggingException(Exception):
    def __init__(self, message, package_id):
        # Set message info
        super.__init__(message)
        self.package_id = package_id

    def log(self, manager=None):
        if manager.log_handler is None:
            print(super().__str__())
        else:
            manager.l(self.package_id, LogLevelEnum.ERROR, super()..__str__())

现在,您可以随时触发日志记录操作,而无需重新构建消息:

try:
    ...
except LoggingException as e:
    e.log(some_manager)
    raise

这使您可以选择真正重新引发错误,如此处所示,或者像您的示例中那样链接它。我强烈建议不要使用链接,除非您有充分的理由这样做。


推荐阅读