Hello: Please refer to the following script:
import sys import twisted.internet.defer import twisted.internet.reactor import twisted.python.log print "Twisted version", twisted.version print "Python version", sys.version class ExceptionToRaise(Exception): pass exception_to_raise = ExceptionToRaise() @twisted.internet.defer.inlineCallbacks def icb_error_maker(): """ Raises an exception implemented as an inline inlineCallbacks """ raise exception_to_raise def pod_error_maker(): """ Raises an exception implemented as a plain old deferred """ deferred = twisted.internet.defer.Deferred() deferred.errback(exception_to_raise) return deferred #ERROR_MAKER_TO_USE = icb_error_maker ERROR_MAKER_TO_USE = pod_error_maker @twisted.internet.defer.inlineCallbacks def intermediate_function3(): print 'intermediate_function3 1' try: yield ERROR_MAKER_TO_USE() except BaseException as exception: print 'intermediate_function3 exception', repr(exception) raise print 'intermediate_function3 2' @twisted.internet.defer.inlineCallbacks def intermediate_function2(): print 'intermediate_function2 1' try: yield intermediate_function3() except BaseException as exception: print 'intermediate_function2 exception', repr(exception) raise print 'intermediate_function2 2' @twisted.internet.defer.inlineCallbacks def intermediate_function1(): print 'intermediate_function1 1' try: yield intermediate_function2() except BaseException as exception: print 'intermediate_function1 exception', repr(exception) raise print 'intermediate_function1 2' def run(): d = intermediate_function1() d.addErrback(twisted.python.log.err) d.addBoth(lambda n: twisted.internet.reactor.stop()) twisted.internet.reactor.callWhenRunning(run) twisted.internet.reactor.run() When ERROR_MAKER_TO_USE = icb_error_maker The output is as follows: Twisted version [twisted, version 13.2.0] Python version 2.7.3 (default, Feb 27 2014, 20:00:17) [GCC 4.6.3] intermediate_function1 1 intermediate_function2 1 intermediate_function3 1 intermediate_function3 exception ExceptionToRaise() intermediate_function2 exception ExceptionToRaise() intermediate_function1 exception ExceptionToRaise() Unhandled Error Traceback (most recent call last): File "/home/daveb/bzr_repo/player_rm2/test2/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1237, in unwindGenerator return _inlineCallbacks(None, gen, Deferred()) File "/home/daveb/bzr_repo/player_rm2/test2/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1099, in _inlineCallbacks result = g.send(result) File "icb_error_test1.py", line 52, in intermediate_function2 yield intermediate_function3() File "/home/daveb/bzr_repo/player_rm2/test2/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1237, in unwindGenerator return _inlineCallbacks(None, gen, Deferred()) --- <exception caught here> --- File "/home/daveb/bzr_repo/player_rm2/test2/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1099, in _inlineCallbacks result = g.send(result) File "icb_error_test1.py", line 37, in intermediate_function3 yield ERROR_MAKER_TO_USE() File "/home/daveb/bzr_repo/player_rm2/test2/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1228, in unwindGenerator gen = f(*args, **kwargs) File "icb_error_test1.py", line 19, in icb_error_maker raise exception_to_raise __main__.ExceptionToRaise: However when ERROR_MAKER_TO_USE = pod_error_maker The output is as follows: Twisted version [twisted, version 13.2.0] Python version 2.7.3 (default, Feb 27 2014, 20:00:17) [GCC 4.6.3] intermediate_function1 1 intermediate_function2 1 intermediate_function3 1 intermediate_function3 exception ExceptionToRaise() intermediate_function2 exception ExceptionToRaise() intermediate_function1 exception ExceptionToRaise() Unhandled Error Traceback (most recent call last): Failure: __main__.ExceptionToRaise: Questions: 1. Why is it that icb_error_maker raises an exception that retains its traceback while pod_error_maker does not? 2. How might one retain the inlineCallback trace when handling Exceptions/Failures from deferreds? (I would prefer a universal method, ie not doing a Try/Reraise at every yield point) ? 3. I have taken a look at the code in twisted/internet/defer.py and I am not sure where the distinction between inlineCallback exceptions and deferred errors are being made. Would someone please elaborate on this process. Thanks
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python