[Twisted-Python] little bits of woven joy
Bruce Mitchener
bruce at cubik.org
Wed Sep 25 12:26:54 MDT 2002
Currently, if you have multiple deferreds in flight and one of them
fails, future failures aren't handled nicely at all. This patch works
on improving that, but isn't perfect yet.
It also handles a few other things ... callbacks that were having an
exception raised didn't display that in the web interface ... and if we
do that, we should just return the Failure back to
Deferred._runCallbacks as well to swap over to the errback chain.
If someone has a good (better) idea on handling the multiple-deferreds
in flight that error out, I'd love to hear it. This is actually causing
other problems as well that this problem doesn't fix .. where sometimes,
parts of the page will be rendered and parts will be formatFailure
output ... and sometimes the web connection never closes down and so the
browser just spins on it. :)
There are a couple of other problems as well, but I don't (yet) have a
good enough handle on them to discuss them, much less play with fixes.
The only other thing in here is a bit more data showing where it tried
to look for the view method when it raises the error.
- Bruce
cvs server: Diffing .
Index: template.py
===================================================================
RCS file: /cvs/Twisted/twisted/web/woven/template.py,v
retrieving revision 1.3
diff -u -r1.3 template.py
--- template.py 25 Sep 2002 18:14:27 -0000 1.3
+++ template.py 25 Sep 2002 18:15:20 -0000
@@ -118,7 +118,8 @@
def renderFailure(ignored, request):
f = failure.Failure()
request.write(widgets.formatFailure(f))
- request.finish()
+ ###request.finish()
+ return f
class DOMTemplate(Resource, View):
@@ -240,6 +241,7 @@
return self.sendPage(request)
except:
renderFailure(None, request)
+ request.finish()
def dispatchResult(self, request, node, result):
"""
@@ -276,11 +278,19 @@
Deal with a callback from a deferred, dispatching the result
and recursing children.
"""
- self.outstandingCallbacks -= 1
- node = self.dispatchResult(request, node, result)
- self.recurseChildren(request, node)
- if not self.outstandingCallbacks:
- return self.sendPage(request)
+ try:
+ self.outstandingCallbacks -= 1
+ node = self.dispatchResult(request, node, result)
+ self.recurseChildren(request, node)
+ if not self.outstandingCallbacks:
+ return self.sendPage(request)
+ except:
+ f = renderFailure(None, request)
+ if self.outstandingCallbacks == 0:
+ request.finish()
+ else:
+ log.msg("Not finishing yet ... still %s remaining" %
self.outstandingCallbacks)
+ return f
def processWidget(self, request, widget, node):
"""
@@ -339,6 +349,7 @@
# Look up either a widget factory, or a dom-mutating method
defaultViewMethod = None
+ sources = [self, domwidgets]
view = DefaultWidget(self.model)
viewMethod = self.templateMethods.getMethodForNode(node)
if viewMethod:
@@ -356,6 +367,7 @@
else:
# Check to see if the viewMethod returns a widget.
(Use IWidget instead?)
maybeWidget = viewMethod(request, node)
+ sources = (maybeWidget)
if isinstance(maybeWidget, domwidgets.Widget):
view = maybeWidget
viewMethod = view.generate
@@ -369,7 +381,7 @@
del view
del result
nodeText = node.toxml()
- raise NotImplementedError, "You specified view name %s on a
node, but no factory_%s method was found." % (viewName, viewName)
+ raise NotImplementedError, "You specified view name %s on a
node, but no factory_%s method was found. Tried looking on %s" %
(viewName, viewName, sources)
return view, viewMethod, result
def handleNode(self, request, node):
Index: widgets.py
===================================================================
RCS file: /cvs/Twisted/twisted/web/woven/widgets.py,v
retrieving revision 1.6
diff -u -r1.6 widgets.py
--- widgets.py 25 Sep 2002 18:14:27 -0000 1.6
+++ widgets.py 25 Sep 2002 18:15:20 -0000
@@ -168,13 +168,16 @@
return self.generateDOM(request, node)
def callback(self, result, request, node):
- self.setData(result)
- data = self.getData()
- if isinstance(data, defer.Deferred):
- data.addCallbacks(self.callback, renderFailure,
callbackArgs=(request, node), errbackArgs=(request,))
- return data
- self.setUp(request, node, data)
- return self.generateDOM(request, node)
+ try:
+ self.setData(result)
+ data = self.getData()
+ if isinstance(data, defer.Deferred):
+ data.addCallbacks(self.callback, renderFailure,
callbackArgs=(request, node), errbackArgs=(request,))
+ return data
+ self.setUp(request, node, data)
+ return self.generateDOM(request, node)
+ except:
+ return renderFailure(None, request)
def setUp(self, request, node, data):
"""Override this setUp method to do any work your widget
More information about the Twisted-Python
mailing list