[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