I fiddled with that a lot to get it right, so my memory of the process is a little hazy. Give it a try!
My issue was that I needed handle_with_processors to *not* catch the exceptions at all - because I wanted to do my own error handling end-to-end by actually returning specific exception types and handling them. Handle_with_processors was hijacking the exceptions. I'd suggest the best case for usability would be that handle_with_processors not have a try block, and leave it up to a higher level wrapper to handle them appropriately. However, I didn't dig deep enough into web.py to see if there's a reason it's done like that, and my overload is working just fine. On Mon, May 20, 2013 at 12:50 PM, Matteo Landi <[email protected]>wrote: > On Sun, May 19, 2013 at 6:19 PM, Shannon Cruey > <[email protected]> wrote: > > The problem is the processor function in the application.py module has a > try > > block in it, so it's redirecting to the internal error handler. I have > > I am looking at the code of the method ``handle_with_processors`` of > the application module: am I wrong saying that the try-catch block > could be safely moved out of the ``process`` function and put around > the line containing ``return process(self.processors)``? This way > processors will be able to handle certain kind of exceptions and still > propagate unhandled ones to the framework (to enable default exception > management). > > What do you think about that? If you don't see any issue I can > provide a pull request with these changes. > > > Regards, > > Matteo > > > successfully overloaded this function in my main module and am able to > > return different status codes as I like. Here's what I did in my main > code: > > (You can see the entire file at > > > > app = ExceptionHandlingApplication(urls, globals(), autoreload=True) > > > > > > Then here's that class: > > > > class ExceptionHandlingApplication(web.application): > > > > """ > > > > This is an overload of the standard web.application class. > > > > Main reason? In application.py, the 'handle_with_processors' function > > > > converts *any* exception into the generic web.py _InternalError. > > > > > > > > This interferes, because we wanna trap the original error an make > > determinations > > > > on how to reply to the client. > > > > > > > > So, we overloaded the function and fixed the error handing. > > > > """ > > > > def handle_with_processors(self): > > > > def process(processors): > > > > try: > > > > if processors: > > > > p, processors = processors[0], processors[1:] > > > > return p(lambda: process(processors)) > > > > else: > > > > return self.handle() > > > > except (web.HTTPError, KeyboardInterrupt, SystemExit): > > > > raise > > > > except InfoException as ex: > > > > # I use a custom HTTP status code to indicate > 'information' > > back to the user. > > > > web.ctx.status = "280 Informational Response" > > > > logger.exception(ex.__str__()) > > > > return ex.__str__() > > > > except SessionError as ex: > > > > logger.exception(ex.__str__()) > > > > # now, all our ajax calls are from jQuery, which sets a > > header - X-Requested-With > > > > # so if we have that header, it's ajax, otherwise we can > > redirect to the login page. > > > > > > > > # a session error means we kill the session > > > > session.kill() > > > > > > > > if web.ctx.env.get("HTTP_X_REQUESTED_WITH") == > > "XMLHttpRequest": > > > > web.ctx.status = "480 Session Error" > > > > return ex.__str__() > > > > else: > > > > logger.debug("Standard Request - redirecting to the > > login page...") > > > > raise web.seeother('/static/login.html') > > > > except Exception as ex: > > > > # web.ctx.env.get('HTTP_X_REQUESTED_WITH') > > > > web.ctx.status = "400 Bad Request" > > > > logger.exception(ex.__str__()) > > > > return ex.__str__() > > > > > > > > return process(self.processors) > > > > > > > > On Sun, May 19, 2013 at 6:46 AM, Matteo Landi <[email protected]> > > wrote: > >> > >> Hi there, > >> > >> What is the best way to manage certain type of exceptions so that they > >> don't produce a '500 Internal Error' HTTP status? > >> > >> First I thought about request decorators but then I realized that > >> decorating *each* request seem to be a bit overkill. Then I thought > >> about application decorators: the documentation even contains an > >> example where a try-except block is put within an handler. So I come > >> up with the following handler: > >> > >> def manage_content_exceptions(handler): > >> web.ctx.logger.info("before_manage") > >> try: > >> return handler() > >> except app.exceptions.ResponseContent as r: > >> return r.content > >> finally: > >> web.ctx.logger.info("after_manage") > >> > >> What happens here is that the finally block is never executed and > >> consequently the exception is caught by the application and an > >> internal error is sent back to the client. > >> > >> Could you please shed some light on the subject and tell me what's > >> wrong with my handler? I even found another discussion [1] about same > >> issue but unfortunately it is unanswered. > >> > >> > >> Regards, > >> > >> Matteo > >> > >> [1] https://groups.google.com/d/msg/webpy/f7IBxCgvIoY/GQxeHKVw8pcJ > >> > >> -- > >> You received this message because you are subscribed to the Google > Groups > >> "web.py" group. > >> To unsubscribe from this group and stop receiving emails from it, send > an > >> email to [email protected]. > >> To post to this group, send email to [email protected]. > >> Visit this group at http://groups.google.com/group/webpy?hl=en. > >> For more options, visit https://groups.google.com/groups/opt_out. > >> > >> > > > > -- > > You received this message because you are subscribed to the Google Groups > > "web.py" group. > > To unsubscribe from this group and stop receiving emails from it, send an > > email to [email protected]. > > To post to this group, send email to [email protected]. > > Visit this group at http://groups.google.com/group/webpy?hl=en. > > For more options, visit https://groups.google.com/groups/opt_out. > > > > > > -- > You received this message because you are subscribed to the Google Groups > "web.py" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/webpy?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > > > -- You received this message because you are subscribed to the Google Groups "web.py" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/webpy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
