[Twisted-Python] Passing additional arguments to errback
Laurens Van Houtven
_ at lvh.io
Thu Sep 5 01:57:00 MDT 2013
Hi,
On Thu, Sep 5, 2013 at 9:24 AM, Maciej Wasilak <wasilak at gmail.com> wrote:
> Thank you for your answer. I'm explicitly interested in the following
> combination:
>
> > .addCallback(cb).addErrback(eb)
>
> If I understand correctly errback "eb" catches errors from both callback
> "cb", and from agent.request (agent.request errors pass through default
> empty errback that re-raises them).
>
Yes, that's exactly what it does :) The difference being that with
.addCallbacks(cb, eb), errors in cb would not be caught by eb.
> > Also, if you want to do scraping with Twisted, consider looking at
> Scrapy, a fully-featured web scraper that uses Twisted internally.
>
> I'm working on CoAP protocol which runs on top of UDP. My actual code is
> request processing (but the problem is the same as in my previous post):
>
> _________________________________________________
> def processRequest(self, request):
> (...)
> d = defer.succeed(request)
> d.addCallback(self.processBlock1)
> d.addCallback(self.dispatchRequest)
> def dispatchRequest(self, request):
> (...)
> resource = self.endpoint.getResourceFor(request)
> if resource is None:
> response = Message(code=NOT_FOUND, payload='Resource not
> found!')
> self.respond(response, request)
> return
> try:
> d = resource.render(request)
> except iot.error.UnallowedMethod:
> response = Message(code=METHOD_NOT_ALLOWED, payload='Method
> not allowed!')
> self.respond(response, request)
> return
> except iot.error.UnsupportedMethod:
> response = Message(code=NOT_IMPLEMENTED, payload='Method not
> implemented!')
> self.respond(response, request)
> return
> delayed_ack = reactor.callLater(EMPTY_ACK_DELAY, self.sendEmptyAck
> , request)
> d.addCallback(self.respond, request, delayed_ack)
> return d
>
> __________________________________________________
>
> I would like to rewrite it to:
>
> __________________________________________________
> def processRequest(self, request):
> (...)
> d = defer.succeed(request)
> d.addCallback(self.processBlock1)
> d.addCallback(self.dispatchRequest
> ).addErrback(self.handleRequestError)
>
> def dispatchRequest(self, request):
> (...)
> resource = self.endpoint.getResourceFor(request)
> if resource is None:
> raise NoResource()
> try:
> d = resource.render(request)
> except iot.error.UnallowedMethod: #Explicit re-rise for this
> example only
> raise UnallowedMethod()
> except iot.error.UnsupportedMethod:
> raise UnsupportedMethod()
> d.addCallback(self.respond, request)
> return d
>
>
> def handleRequestErrors(self, failure, request???)
> # handle exceptions, send error response to client
>
> _______________________________________________
>
> I would like to handle Exceptions in handleRequestErrors(). However
> handleRequestErrors() has to send a response to the client, so it needs the
> request, and I don't know how to pass it from inside dispatchRequest().
>
You don't have to do it from in there. You can do .addErrback(handleErrors,
request), since it's all the same request object, right?
> I see two possibilities:
> 1. Pass request inside Failure object
> 2. Leave the original code (process errors inside callback)
>
Both of those would work, but see above :)
Two random pieces of code review:
1. It seems self.endpoint is a t.w.s.Site object. That's kind of confusing,
since twisted has an "endpoint" concept that's one step removed from a Site
(endpoints connect or listen with factories, a Site is a factory). You
might want to reconsider that name :)
2. It's kind of strange to start with defer.succeed() and then start making
a callback chain IMHO, but it's not wrong, really.
cheers
lvh
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/twisted-python/attachments/20130905/9051c3e0/attachment-0002.html>
More information about the Twisted-Python
mailing list