处理我的类层次结构中的异常

时间:2012-12-19 21:58:50

标签: python architecture

我有类似的层次结构和类似的代码:

class FrontendException:
    pass    
class BackendException:
    pass
class BackendRequest:
    def exec():
        raise BackendException()

class Frontend:
    def cmd_a():
        BackendRequest().exec()

    def cmd_b():
        BackendRequest().exec()

目标是让开发人员能够在Frontend的{​​{1}}个函数中使用cmd_x个对象和例外进行操作。

基本上,我需要一个处理常见Frontend类型的地方来筹集BackendException。例如:

FrontendException

这将在每个class Frontend: def cmd_a(): try: BackendRequest().exec() except BackendException as e: raise FrontendException() 函数中重复出现!太难看了!并且它与cmd_x事物一起运作!我想删除重复的异常处理。 有任何建议吗?

顺便说一下,我的解决方案,但我发现它也很难看,所以在你试图建议我之后再看看它。也许你会建议我解决我的问题。

Backend

编辑:好的,是的,我知道,我不需要创建很多类来构建简单的API。但是,让我们看看结果中我需要什么:

class BaseFrontend:
    def exec_request(req):
        try:
            return req.exec()
        except BackendException as e:
            raise FrontendException
class Frontend(BaseFrontend):
    def cmd_a():
        result self.exec_request(BackendRequest())
    def cmd_b():
        result self.exec_request(BackendRequest())

此管理器需要访问HTTP REST服务才能执行每个命令。所以,如果我在REST请求期间收到错误,我将需要引发异常APIManagerException - 我不能离开class APIManager: def cmd_a(): ... def cmd_b(): ... ,因为APIManager用户不知道是什么{{ 1}},如果他将错误的raw pycurl exception作为pycurl的参数,他将会被pycurl error混淆。 因此,我需要针对一些常见案例提出信息性异常。让它成为一个例外 - ID。但我不希望每次在每个命令中重复cmd_x阻止每个pycurl请求。实际上,我想在APIManagerException中处理一些错误,而不是解析pycurl错误。

1 个答案:

答案 0 :(得分:0)

您可以创建一个包装所有前端调用的装饰器,捕获BackendExceptions,并在抛出它们时引发FrontendException。 (老实说,虽然不清楚为什么FrontendBackend是类而不是一组函数。)见下文:

class FrontendException:
    pass    
class BackendException:
    pass
class BackendRequest:
    def exec():
        raise BackendException()

class Frontend:

    def back_raiser(func):
        def wrapped(*args, **kwargs):
            try:
                func(*args, **kwargs)
            except BackendException:
                raise FrontendException
        return wrapped

    @back_raiser
    def cmd_a():
        BackendRequest().exec()

    @back_raiser
    def cmd_b():
        BackendRequest().exec()