<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hi all,<div><br></div><div>I 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> NOT_IMPLEMENTED = 501</b></div><div><b> BAD_REQUEST = 400</b></div><div><span class="Apple-tab-span" style="white-space:pre"><b>        </b></span></div><div><b> def writeError(self, failure, request, *args, **kw):</b></div><div><b> failure.trap(FWGException)</b></div><div><b> request.setResponseCode(self.errorCode)</b></div><div><b> request.write("Error handling request: %s" % failure.getErrorMessage())</b></div><div><b> request.finish()</b></div><div><b><br></b></div><div><b> def writeResult(self, result, request, *args, **kw):</b></div><div><b> self.writexml(request)</b></div><div><b> request.finish()</b></div><div><b><br></b></div><div><b> def render_GET(self, request):</b></div><div><b> self.process=self.db.runInteraction(self.processForm,request)</b></div><div><b> self.process.addCallbacks(self.writeResult, self.writeError, [request], {}, [request], {})</b></div><div><b> 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> def __init__(self, task, db, config):</b></div><div><b> DeferredPostHandler.__init__(self,db)</b></div><div><b> self.config = config</b></div><div><b> self.task = task</b></div><div><b> self.errorCode = http.OK</b></div><div><b><br></b></div><div><b> def processForm(self, cursor, request):</b></div><div><b><br></b></div><div><b> if self.task == 'add':</b></div><div><b> self.addCollection(cursor, request)</b></div><div><b><br></b></div><div><b> elif self.task == 'delete':</b></div><div><b> self.deleteCollection(cursor, request)</b></div><div><b> </b></div><div><b> else:</b></div><div><b> self.errorCode = DeferredPostHandler.NOT_IMPLEMENTED</b></div><div><b> fail = Failure(FWGException("Unsupported Task"))</b></div><div><b> self.process.errback(fail)</b></div><div><b><br></b></div><div><b> def addCollection(self, cursor, request):</b></div><div><b> fail = None</b></div><div><b> if self.isValidAddRequest(request):</b></div><div><b> pass</b></div><div><b> else:</b></div><div><b> self.errorCode = DeferredPostHandler.BAD_REQUEST</b></div><div><b> fail = Failure(FWGException("Missing Parameter"))</b></div><div><b><br></b></div><div><b> if fail:</b></div><div><b> self.process.errback(fail);</b></div><div><b><br></b></div><div><b> def deleteCollection(self, cursor, request):</b></div><div><b> print 'Delete Collection'</b></div><div><b><br></b></div><div><b> def isValidAddRequest(self, request):</b></div><div><b> 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 </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> File "startserver.py", line 23, in <module></b></div><div><b> reactor.run()</b></div><div><b> 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> self.mainLoop()</b></div><div><b> 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> self.runUntilCurrent()</b></div><div><b>--- <exception caught here> ---</b></div><div><b> 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> f(*a, **kw)</b></div><div><b> 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> self._startRunCallbacks(result)</b></div><div><b> 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> raise AlreadyCalledError</b></div><div><b>twisted.internet.defer.AlreadyCalledError: </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>