Search code examples
error-handlingpylons

Handling non-fatal exceptions in Pylons


In my Pylons application I'd like to be able to throw exceptions anywhere in the code and have the non-fatal ones intercepted in a central point, so that I could return a "friendly" error page such as "Sorry, I can't do that".
Fatal exceptions instead should go to the default error handler, that sends me an error report by email and returns to the user the standard "internal server error".
Right now I'm using something like this in BaseController.__call__:

try:
    return WSGIController.__call__(self, environ, start_response)
except Exception, exc:
    if self.is_nonfatal_exception(exc):
        start_response("200 OK", [("Content-type", "text/plain")])
        return ["Sorry!"]
    raise

but is this the recommended way?


Solution

  • Yes, this looks fine.

    Also take a look at pylons.controllers.utils.abort(). Anywhere in your controller code you can do abort(some_http_code[, message]). Typical HTTP codes to be used with this would be 404 ("Page not found", client is looking for something that's not there), 403 ("Forbidden", user is not allowed to access that page/resource), 400 ("Bad request", request parameter validation failed) and others. This function also works by throwing special exceptions, then catching them and returning standard error pages somewhere from middleware stack. Of course, you can also call abort() from models and other places, not just controllers. But this would be bad style, mixing controller logic with model logic, jumping levels of abstractions.

    Finally, for error conditions that you expect to be common, consider not using exceptions, but using return codes of functions instead. Exceptions that bubble up long way may break encapsulation (distant components need to know about each other's exceptions, and how these should be handled) .