[Twisted-Python] Flow: better synchronous exceptions [patch]
Christopher Armstrong
radix at twistedmatrix.com
Mon Jun 23 20:46:21 MDT 2003
Here's a patch that changes semantics of Stage.next. Currently,
if a Deferred errbacks with an exception that you haven't
explicitly trapped, Stage.next will raise the Failure object
(via the failure's trap method). I've changed this so it rather
does `raise type(failure.value), failure.value, failure.tb'.
What this means is that you can write code like this:
d = flow.wrap(getDeferred())
yield d
try:
result = d.next()
except ParticularError, e:
traceback.print_exc()
Two benefits here. One, I can actually say
"except ParticularError" -- before, the type of the exception
raised would be Failure. Two, the traceback printed by
traceback.print_exc() will actually be useful and show you the
stack trace of the original code that raised the error, rather
than the traceback starting from the Failure.trap call.
Of course, the traceback is cleaned once Deferred.runCallbacks
finishes, but this only matters when the Deferred is resolved
synchronously, as far as I can tell. In that case, you will
get a pretty useless traceback, but it won't be any more
useless than the tracebacks that used to be reported.
The only drawback I see is that it breaks a flow test. :-)
FailTest: exceptions.ZeroDivisionError raised instead of Failure
Because the test is expecting a Failure to be raised, not
the original, and more useful, exception.
self.assertRaises(flow.Failure, list, flow.Block(badgen()))
Clark, I'll be waiting for confirmation from you to commit this or
trash it.
--
Twisted | Christopher Armstrong: International Man of Twistery
Radix | Release Manager, Twisted Project
---------+ http://twistedmatrix.com/users/radix.twistd/
-------------- next part --------------
? better-synchronous-exceptions.diff
? flow.xhtml
Index: flow.py
===================================================================
RCS file: /cvs/Twisted/sandbox/flow.py,v
retrieving revision 1.107
diff -u -r1.107 flow.py
--- flow.py 22 Jun 2003 06:45:12 -0000 1.107
+++ flow.py 24 Jun 2003 02:35:46 -0000
@@ -297,9 +297,19 @@
return self.results.pop(0)
if self.stop:
raise StopIteration()
+
if self.failure:
self.stop = True
- return self.failure.trap(*self._trap)
+
+ cr = self.failure.check(*self._trap)
+
+ if cr:
+ return cr
+
+ if self.failure.tb:
+ raise self.failure.value.__class__, self.failure.value, self.failure.tb
+ raise self.failure.value
+
raise NotReadyError("Must 'yield' this object before calling next()")
def _yield(self):
@@ -492,11 +502,13 @@
obj = obj()
typ = type(obj)
+
if typ is type([]) or typ is type(tuple()):
return _List(obj)
+
if typ is type(''):
return _String(obj)
-
+
if isinstance(obj, defer.Deferred):
return _Deferred(obj, *trap)
More information about the Twisted-Python
mailing list