Reputation: 23
I have a problem with multiple decorators with spyne. I want to add universal try/except decorator to each method in class. My code looks like this:
def try_except(fn):
def wrapped(*args, **kwargs):
try:
return fn(*args, **kwargs)
except Exception:
do_sth()
return wrapped
class A(ServiceBase):
@rpc(Unicode, Integer, _returns=[Boolean, Integer], _out_variable_names=["FooResult", "bar"])
@try_except
def Foo(self, foo, bar):
do_sth()
return True, 0
With @try_except I get number of arguments error, what am I doing wrong?
Upvotes: 2
Views: 643
Reputation: 8001
I don't recommend decorators. Not because they are not supported, but because they are not very powerful and also have cryptic behaviour.
For exception handling, you can override call_wrapper
function of either Application
or ServiceBase
in a class in your project and use it instead of stock Spyne classes. You should have your try/except block surround the super()
call.
See API docs for ServiceBase.call_wrapper and Application.call_wrapper.
You don't like to do this? You can add event handlers to your service classes or applications. The events example can get you started.
You still want to use decorators? See this FAQ entry. Quoting the relevant bits:
from decorator import decorator def _do_something(func, *args, **kw): print "before call" result = func(*args, **kw) print "after call" return result def my_decor(f): return decorator(_do_something, f) class SomeService(ServiceBase): @my_decor @srpc(Integer, _returns=Integer) def testf(first): return first
Note that the place of the decorator matters. Putting it before @srpc will make it run once, on service initialization. Putting it after will make it run every time the method is called, but not on initialization.
Again, don't use decorators!!
You have been warned :)
Upvotes: 1