[Twisted-Python] inlineCallbacks loses custom exception type?
Benjamin Rutt
rutt.4 at osu.edu
Wed Dec 5 22:36:51 EST 2012
Hi,
I am hitting an issue with inlineCallbacks-decorated functions. It seems
that from within an inlineCallbacks-decorated func, if you yield on another
deferred-returning func, and that deferred-returning func returns a
deferred which will errback with a Failure wrapping a user defined
exception type, then the user defined exception gets repackaged as a common
Exception by the time you are in the inlineCallbacks-decorated function.
It seems to be related to the fact that inside an inlineCallbacks-decorated
func, if you yield on a func, and that func returns a deferred which errs
back, twisted will convert the errback into a synchronous exception that it
raises for you. That’s all a bit wordy, so maybe some code will help
clarify:
$ cat inlinecallbacks-loses-exception-types.py
#!/usr/bin/env python
import sys, traceback
from twisted.internet import defer, reactor
class MyException(Exception):
pass
def go2():
"An ordinary deferred-returning function that will return a deferred
which is ready to errback()"
try:
raise MyException('xyz')
except Exception as e:
return defer.fail() # errs back with current exception context
return defer.succeed(1) # unreachable code
@defer.inlineCallbacks
def go_inlinecb():
try:
x = yield go2()
print 'no exception raised'
except MyException as e:
print 'got my custom exception'
traceback.print_exc()
except Exception as e:
print 'got a garden variety exception'
traceback.print_exc()
def go_noinlinecb():
d = go2()
def cb(data):
print 'got data in cb: %s' % (data)
def eb(failure):
try:
failure.raiseException()
except MyException as e:
print 'got my custom exception'
traceback.print_exc()
except Exception as e:
print 'got a garden variety exception'
traceback.print_exc()
d.addCallbacks(cb, eb)
if sys.argv[1] == 'inline':
reactor.callWhenRunning(go_inlinecb)
elif sys.argv[1] == 'noinline':
reactor.callWhenRunning(go_noinlinecb)
reactor.callLater(2, reactor.stop)
reactor.run()
$ ./inlinecallbacks-loses-exception-types.py inline
got a garden variety exception
Traceback (most recent call last):
File "./inlinecallbacks-loses-exception-types.py", line 21, in go_inlinecb
x = yield go2()
Exception: xyz
$ ./inlinecallbacks-loses-exception-types.py noinline
got my custom exception
Traceback (most recent call last):
File "./inlinecallbacks-loses-exception-types.py", line 36, in eb
failure.raiseException()
File
"/sw/external/twisted-py27-11.0.0/lib/python/twisted/python/failure.py",
line 338, in raiseException
raise self.type, self.value, self.tb
MyException: xyz
So as you can see, it seems that if you use inlineCallbacks, you cannot
‘except MyException’ and catch your own custom exceptions. Somehow a
generic Exception is constructed. Is there any workaround or is this a
known issue?
Thanks,
--
Benjamin Rutt
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://twistedmatrix.com/pipermail/twisted-python/attachments/20121205/8fa4c263/attachment.htm
More information about the Twisted-Python
mailing list