Something I've struggled with for a long time I've finally solved, right or wrong :-)
My application is about 95% ajax based, so most of my calls to the server are XMLHttpRequest. I keep stuff in the session, and a 2 minute heartbeat keeps an active user list in my db. All pages are controlled by role based security, so users can only get the content they need. This complexity creates a lot of room for errors, and I need to communicate precisely with the user, as well as pass detailed info/exception information back to the client. The default behavior in web.py seems to be to trap all python exceptions behind the built in _InternalError, which will throw back an "internal server error" to the client as an HTTP 500 status. This isn't precise enough for me to interact with the user as I'd like. Also, I'm trying to be very "pythonic" in my code so I'm raising custom exceptions for errors *as well as* informational cases. I've got about 20 custom exceptions defined. Finally, every request to the server goes through an app_processor, so I can verify that the user is still valid and has an active session. (*my* internal session mechanis, not the web.py session, although I use the latter to implement mine.) Here's what I did to make it all work. (This is snippets of course, not the whole file.) class ExceptionHandlingApplication(web.application): """ This is an overload of handle_with_processors from the standard web.application class. """ 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: # we're using 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: # indicates the code determined this session is done. 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. # and the client handles the different HTTP status codes! # 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) And here's how I set up the application: app = ExceptionHandlingApplication(urls, globals(), autoreload=True) app.add_processor(auth_app_processor) I hope this helps someone! NSC -- 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 webpy+unsubscr...@googlegroups.com. To post to this group, send email to webpy@googlegroups.com. Visit this group at http://groups.google.com/group/webpy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.