Personalize your Error pages in Turbogears 2
Friday, August 7th, 2009 | Web
I was looking for a way to propagate exceptions from my tg2 app to the ErrorController to permit to propagate errors from controllers to the user. To generate errors and show them you usually have to redirect to /error/document and pass as parameters the error message and error code, but this isn’t really flexible and also modern languages have a really good feature to propagate errors: Exceptions.
So I was looking for a way to raise a webob.exc.HTTPForbidden, place a message inside it and let the ErrorController render the message. Usually you don’t want to tell to the user what went wrong with your 500 server side exception, but you might want to tell to the user why he can’t do what he is trying to do, let him know why it is Forbidden to him.
First thing you can easily do is check for resp.status_int inside your ErrorController.document and fetch only 403 error (the forbidden one). This permits to create a specific message for Forbidden errors, but doesn’t tell much to the user about why it is forbidden. webob.exc.HTTPForbidden permits to set a detail message and also generates an error page, but the turbogears stack when gets a status code different from 200 hooks the response and calls the ErrorController.document to generate a new response. This way your HTTPForbidden exception is lost forever.
Actually it isn’t really lost, as you can access the previous error page from request.environ.get(‘pylons.original_response’). If you want a quick solution you can hook ErrorController if status_int is 403 and return the original_response instead of rendering ErrorController.document template.
But the original response isn’t really nice and you usually want to adapt it.
My solution has been to create a new ApplicationError(webob.exc.Forbidden) class defined as the following one:
from webob.exc import HTTPForbidden
try:
from string import Template
except ImportError:
from webob.util.stringtemplate import Template
class HTTPMyAppError(HTTPForbidden):
body_template_obj = Template('''<div>${detail}</div>''')
def __init__(self, msg):
super(HTTPMyAppError, self).__init__(msg)
This by itself doesn’t change a lot as you will get the same ugly page with simply a div around your error. But now by using BeautifoulSoup you are able to get only your message from the original_response inside your ErrorController.document action.
if resp.status_int == 403: title = "Application Error" message = "We can't perform this, reason was:" details = str(BeautifulSoup(resp.body).find('div'))
Simply personalize your ErrorController.document template and display your details somewhere and you will be able to report errors to your users by simply doing something like raise HTTPMyAppError(’You have already used this registration code’)
I know that this isn’t a really great solution as you have to parse your already generated error page to fetch only the error message and generate a new error page, if anyone has a better solution that permits to directly access the exception instance feel free to tell me!
-
Rental Property Management
-
robert
-
axant
Search
Archives
- January 2012
- November 2011
- October 2011
- July 2011
- June 2011
- May 2011
- April 2011
- March 2011
- February 2011
- January 2011
- December 2010
- November 2010
- September 2010
- August 2010
- July 2010
- May 2010
- April 2010
- March 2010
- February 2010
- January 2010
- December 2009
- November 2009
- October 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- December 2008
- November 2008
- October 2008
- August 2008