简体   繁体   English

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

[英]re-raise exception from method as argument

I have a method that needs some wrapping called joule, so I wrap that joule method inside a wrapper called respond (which you will see shortly): 我有一个需要包装的方法,称为焦耳,因此我将joule方法包装在一个名为respond的包装器中(稍后将看到):

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

I have a wrapper called respond : 我有一个包装叫做respond

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

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

The actual method that gets called and raises an Exception : 被调用并引发Exception的实际方法:

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

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

For some reason, the re-raised exception does not seem to get caught in the respond wrapper! 由于某种原因,重新引发的异常似乎没有被响应包装捕获! Can you folks help me understand what am I doing incorrectly here? 你们可以帮我了解我在这里做错了什么吗?

If this helps, the exception being thrown by sqlalchemy is (please note that this is a scenario being forcibly created to handle the exception correctly): 如果这有帮助,则由sqlalchemy抛出异常(请注意,这是为了强制正确处理此异常而创建的方案):

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

You are misunderstanding how exception handling works. 您误解了异常处理的工作原理。 Exception handling operates on the stack frame of called functions. 异常处理在被调用函数的堆栈框架上进行。

In the example you give, someclass.respond does not actually invoke somemodule.joule , instead wherever the line that you have written in your example, which is some outer context is the place that receives the uncaught exception. 在您给出的示例中, someclass.respond实际上并不会调用somemodule.joule ,而是在示例中您所写的行中的任何外部上下文中都将接收未捕获的异常。 Thus someclass.respond can't possibly handle the exception thrown by somemodule.joule . 因此someclass.respond可能无法处理somemodule.joule引发的somemodule.joule

There are other ways to achieve what you are trying to accomplish, but I would need more context in order to give you a better suggestion. 还有其他方法可以实现您要实现的目标,但是我需要更多的上下文信息才能为您提供更好的建议。

To make this a bit more concrete, let's say that foo contains the example line you gave: 为了更具体一点,假设foo包含您提供的示例行:

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

You could add the try block to foo to handle the exception thrown by somemodule.joule . 您可以在foo添加try块,以处理somemodule.joule引发的somemodule.joule This would look like this: 看起来像这样:

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

Alternatively, if the whole purpose for someclass.respond is to handle this exception, then you should move the invocation of somemodule.joule inside of someclass.respond . 另外,如果整个目的someclass.respond是处理这个异常,那么你应该移动的调用somemodule.joule someclass.respond You could even do this more than one way. 您甚至可以通过多种方式执行此操作。 You could generically take a function and its arguments, and apply that function to the arguments inside of someclass.respond or you could just directly do the invocation inside of someclass.respond . 您通常可以采用一个函数及其参数,然后将该函数应用于someclass.respond内部的参数,或者可以直接在someclass.respond内部进行调用。

Let's take the first approach, since you've said that you don't want to repeat the exception handling. 让我们采用第一种方法,因为您已经说过不想重复异常处理。 I'll call this new method exception_catcher : 我将这个新方法称为exception_catcher

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

Now the foo context will look like this: 现在, foo上下文将如下所示:

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

Note that exception_catcher is taking somemodule.joule as an argument, and the remaining arguments will be passed to somemodule.joule from within exception_catcher . 需要注意的是exception_catcher正在somemodule.joule作为参数,而其余的参数将被传递到somemodule.joule从内部exception_catcher

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM