类范围的异常处理程序

时间:2019-08-07 20:25:50

标签: python python-3.x exception

我想实现一种方法来全局处理通过我的应用程序发出的类中的异常,而不是在调用站点处处理它们,因为这将导致大量重复代码。

例如,假设我有一个像这样的课程:

class handler():
    def throws_value_error(self):
        raise ValueError

    def throws_not_implemented_error(self):
        raise NotImplementedError

    # ... Imagine there are hundreds of these

在此处理程序类中,我希望所有ValueErrorNotImplementedError都以相同的方式进行处理-一条消息显示[ERROR]: ...,其中...是来自特定实例的详细信息。

而不是再现TON:

try:
    #...
except Exception as e:
    # Catch the instances of the exception and handle them
    # in more-or-less the same way here

我想在类上实现一个可实现此目的的单一方法:

def exception_watcher(self):
    # Big if...elif...else for handling these types of exceptions

然后,在类中提供任何Exception时将调用此方法。

我的动机是使用它来实现一种通用的控制器接口,其中控制器方法可以抛出异常的子类(例如-BadRequestException,它是Error400Exception的子类)。从那里,处理程序可以调度一种方法,以使用针对异常类型的错误代码正确地配置响应,并另外向消费者返回有用的答复。

很明显,没有此调度程序,这是可行的-但这种方式肯定可以节省大量重复代码(并因此减少错误)。

我已经在互联网上进行了很多挖掘工作,但没有发现任何东西。诚然,我从Spring Boot Framework借用了这种模式。我也将接受非Python语言作为答案(只要您能告诉我正确的方法!)

任何帮助将不胜感激-谢谢!

1 个答案:

答案 0 :(得分:1)

在不更改其核心功能的情况下修改功能正是装饰器的目的。看一下此示例,然后尝试运行它:

def catch_exception(func):
    def wrapped(self, *args, **kwargs):
        try:
            return func(self, *args, **kwargs)
        except ValueError:
            self.value_error_handler()
        except NotImplementedError:
            self.ni_error_handler()
    return wrapped

class Handler:
    def value_error_handler(self):
        print("found value error")

    def ni_error_handler(self):
        print("found not implemented error")

    @catch_exception
    def value_error_raiser(self):
        raise ValueError

    @catch_exception
    def ni_error_raiser(self):
        raise NotImplementedError

h = Handler()
h.value_error_raiser()
h.ni_error_raiser()

由于使用了@catch_exception装饰器,因此装饰后的方法不会引发经过校准的错误;而是调用wrapped的try / except块中定义的相应方法,并打印一条消息。

虽然这并非您所要求的,但我认为此解决方案总体上更易于管理。您既可以选择要定期引发异常的方法,又可以选择catch_exception处理哪些方法(通过确定修饰的方法),还可以通过在内部编写额外的except块来增加其他异常类型的未来行为wrapped,并将相应的方法添加到Handler类中。

请注意,这不是一个“干净”的解决方案,因为wrapped希望知道selfHandler的一个实例,因为它调用了很多方法,甚至虽然它是Handler类之外的一个函数...但是,嘿,那是Python的鸭子为您输入的:-P