<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hi all,<div><br></div><div>I &nbsp;am writing a restful twisted (8.1.0) server and am trying to return useful error statuses from requests. The problem is that even following the documentation extremely carefully I am getting an AlreadyCalled Error every time I generate a failure. Here is my main class (leaving out code that I feel is not relevant to the question:</div><div><br></div><div><div><b>from xml.dom import minidom</b></div><div><b>from twisted.web import server, resource</b></div><div><b><br></b></div><div><b>from FWGException import FWGException</b></div><div><b><br></b></div><div><b>class DeferredPostHandler(resource.Resource,minidom.Document):</b></div><div><b><br></b></div><div><b>&nbsp;&nbsp; &nbsp;NOT_IMPLEMENTED = 501</b></div><div><b>&nbsp;&nbsp; &nbsp;BAD_REQUEST = 400</b></div><div><span class="Apple-tab-span" style="white-space:pre"><b>        </b></span></div><div><b>&nbsp;&nbsp; &nbsp;def writeError(self, failure, request, *args, **kw):</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;failure.trap(FWGException)</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;request.setResponseCode(self.errorCode)</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;request.write("Error handling request: %s" % failure.getErrorMessage())</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;request.finish()</b></div><div><b><br></b></div><div><b>&nbsp;&nbsp; &nbsp;def writeResult(self, result, request, *args, **kw):</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;self.writexml(request)</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;request.finish()</b></div><div><b><br></b></div><div><b>&nbsp;&nbsp; &nbsp;def render_GET(self, request):</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;self.process=self.db.runInteraction(self.processForm,request)</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;self.process.addCallbacks(self.writeResult, self.writeError, [request], {}, [request], {})</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return server.NOT_DONE_YET</b></div><div><br></div><div><br></div><div>I have a handler that extends this</div><div><br></div><div><b>from DeferredPostHandler import DeferredPostHandler</b></div><div><div><b>from twisted.web import http</b></div><div><b>from twisted.python.failure import Failure</b></div><div><b>from FWGException import FWGException</b></div><div><b><br></b></div><div><b>class CollectionAdminHandler(DeferredPostHandler):</b></div><div><b><br></b></div><div><b>&nbsp;&nbsp; &nbsp;def __init__(self, task, db, config):</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;DeferredPostHandler.__init__(self,db)</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;self.config = config</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;self.task = task</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;self.errorCode = http.OK</b></div><div><b><br></b></div><div><b>&nbsp;&nbsp; &nbsp;def processForm(self, cursor, request):</b></div><div><b><br></b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if self.task == 'add':</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;self.addCollection(cursor, request)</b></div><div><b><br></b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;elif self.task == 'delete':</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;self.deleteCollection(cursor, request)</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else:</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;self.errorCode = DeferredPostHandler.NOT_IMPLEMENTED</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fail = Failure(FWGException("Unsupported Task"))</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;self.process.errback(fail)</b></div><div><b><br></b></div><div><b>&nbsp;&nbsp; &nbsp;def addCollection(self, cursor, request):</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;fail = None</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if self.isValidAddRequest(request):</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pass</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else:</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;self.errorCode = DeferredPostHandler.BAD_REQUEST</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fail = Failure(FWGException("Missing Parameter"))</b></div><div><b><br></b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if fail:</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;self.process.errback(fail);</b></div><div><b><br></b></div><div><b>&nbsp;&nbsp; &nbsp;def deleteCollection(self, cursor, request):</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;print 'Delete Collection'</b></div><div><b><br></b></div><div><b>&nbsp;&nbsp; &nbsp;def isValidAddRequest(self, request):</b></div><div><b>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return 'title' in request.args and 'category' in request.args and 'date' in request.args</b></div><div><br></div><div><br></div><div>Unfortunately whenever I call&nbsp;</div><div><br></div><div><br></div><div>self.process.errback(fail)</div><div><br></div><div>I get the following stack trace in my log</div><div><br></div><div><br></div><div><div><b>Traceback (most recent call last):</b></div><div><b>&nbsp;&nbsp;File "startserver.py", line 23, in &lt;module&gt;</b></div><div><b>&nbsp;&nbsp; &nbsp;reactor.run()</b></div><div><b>&nbsp;&nbsp;File "/Library/Python/2.5/site-packages/Twisted-8.1.0-py2.5-macosx-10.5-i386.egg/twisted/internet/base.py", line 1048, in run</b></div><div><b>&nbsp;&nbsp; &nbsp;self.mainLoop()</b></div><div><b>&nbsp;&nbsp;File "/Library/Python/2.5/site-packages/Twisted-8.1.0-py2.5-macosx-10.5-i386.egg/twisted/internet/base.py", line 1057, in mainLoop</b></div><div><b>&nbsp;&nbsp; &nbsp;self.runUntilCurrent()</b></div><div><b>--- &lt;exception caught here&gt; ---</b></div><div><b>&nbsp;&nbsp;File "/Library/Python/2.5/site-packages/Twisted-8.1.0-py2.5-macosx-10.5-i386.egg/twisted/internet/base.py", line 677, in runUntilCurrent</b></div><div><b>&nbsp;&nbsp; &nbsp;f(*a, **kw)</b></div><div><b>&nbsp;&nbsp;File "/Library/Python/2.5/site-packages/Twisted-8.1.0-py2.5-macosx-10.5-i386.egg/twisted/internet/defer.py", line 243, in callback</b></div><div><b>&nbsp;&nbsp; &nbsp;self._startRunCallbacks(result)</b></div><div><b>&nbsp;&nbsp;File "/Library/Python/2.5/site-packages/Twisted-8.1.0-py2.5-macosx-10.5-i386.egg/twisted/internet/defer.py", line 298, in _startRunCallbacks</b></div><div><b>&nbsp;&nbsp; &nbsp;raise AlreadyCalledError</b></div><div><b>twisted.internet.defer.AlreadyCalledError:&nbsp;</b></div><div><b><br></b></div><div><b><br></b></div><div>I can not understand why this is happening :-( Can anybody help?</div><div><br></div><div>BTW I am using POST instead of PUT because my client can't do PUT</div><div><br></div><div>Conrad Winchester</div><div><br></div></div><div><br></div></div><div><br></div></div></body></html>