从方法重新引发异常作为参数

时间:2015-03-31 23:44:12

标签: python exception

我有一个方法需要一些名为joule的包装,所以我将joule方法包装在一个名为respond的包装器中(你很快就会看到):

someclass.respond(somemodule.joule(someArgument, someStrategy), 202)

我有一个名为respond的包装器:

@classmethod
def respond(cls, method, successStatus):
    try:
        method, successStatus

    except Exception as e:
        return {
            'status': 500,
            'message': str(e)
        }

调用的实际方法并引发Exception

def joule(params, strategy):
    try:
        return strategy(params)

    finally:
        session.rollback()
        conn.execute('UNLOCK TABLES')

出于某种原因,重新引发的异常似乎没有被响应包装器捕获!你能帮助我理解我在这里做错了什么吗?

如果这有帮助,sqlalchemy抛出的异常是(请注意,这是强制创建的方案,以正确处理异常):

ProgrammingError: (ProgrammingError) (1146, u"Table 'matrix.vmop_queue' doesn't exist") 'LOCK TABLES vmop_queue WRITE' ()

1 个答案:

答案 0 :(得分:1)

您误解了异常处理的工作原理。异常处理在被调用函数的堆栈帧上运行。

在您给出的示例中,someclass.respond实际上并不调用somemodule.joule,而是在您的示例中写入的行,即某些外部上下文是接收未捕获异常的位置。因此someclass.respond无法处理somemodule.joule抛出的异常。

还有其他方法可以实现您想要实现的目标,但我需要更多背景知识才能为您提供更好的建议。

为了使这一点更加具体,让我们说foo包含您给出的示例行:

def foo():
    someclass.respond(somemodule.joule(someArgument, someStrategy), 202)

您可以将try块添加到foo以处理somemodule.joule引发的异常。这看起来像这样:

def foo():
    try:
        someclass.respond(somemodule.joule(someArgument, someStrategy), 202)
    except Exception as e:
        pass # do something with the exception here

或者,如果someclass.respond的整个目的是处理此异常,那么您应该在somemodule.joule的内移动someclass.respond 的调用。您甚至可以通过多种方式实现这一目标。你可以通常使用一个函数及其参数,并将该函数应用于someclass.respond内的参数,或者你可以直接在someclass.respond内部进行调用。

我们采取第一种方法,因为您已经说过您不想重复异常处理。我将这种新方法称为exception_catcher

def exception_catcher(func, *args):
    try:
        return func(*args)
    except Exception as e:
        pass # do whatever you want to the exception

现在foo上下文将如下所示:

def foo():
    exception_catcher(somemodule.joule, someArgument, someStrategy)

请注意,exception_catchersomemodule.joule作为参数,其余参数将从somemodule.joule内传递到exception_catcher