Reputation: 1045
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):
someclass.respond(somemodule.joule(someArgument, someStrategy), 202)
I have a wrapper called 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
:
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):
ProgrammingError: (ProgrammingError) (1146, u"Table 'matrix.vmop_queue' doesn't exist") 'LOCK TABLES vmop_queue WRITE' ()
Upvotes: 1
Views: 61
Reputation: 9770
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. Thus someclass.respond
can't possibly handle the exception thrown by 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:
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
. 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
. 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
.
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
:
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:
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
.
Upvotes: 1