Latest Version: 0.9.6.2
  Dashboard > Pylons Official Docs > Home > Error Documents
  Pylons Official Docs Log In | Sign Up   View a printable version of the current page.  
  Error Documents
Added by James Gardner, last edited by Philip Jenvey on Aug 01, 2007  (view change) show comment
Labels: 
(None)

Introduction

When an application returns a status code other than 200, which is the code for "everything went fine", you might wish to display a message to the user explaining what happened with an error document.

Pylons provides a facility for displaying customized error messages to users via the ErrorDocuments middleware. For those familiar with Apache's ErrorDocument directive, Pylons' ErrorDocuments provides similar functionality.

If an error document is not provided by an application, users will see the browser's default page for that error, or a blank screen, depending on their browser.

The Default Setup

Newly created Pylons applications come configured with the ErrorDocuments middleware enabled. The middleware is setup to call Pylons error_mapper function; which in turn calls the application's ErrorController. The ErrorController renders the actual error document shown to the user; it uses Pylons' error_document_template HTML by default.

Every part of the error documents system can be configured and customized to provide whatever error handling you like.

Disabling Error Documents Support

To disable error documents, just remove the following lines from your config/middleware.py file:

1
2
3
# Display error documents for 401, 403, 404 status codes (if debug is disabled also
# intercepts 500)
app = ErrorDocuments(app, global_conf, mapper=error_mapper, **app_conf)

Any status codes will no longer be intercepted.

Changing the template

To use a different template for the error documents, modify your ErrorController (in controllers/error.py). Change the document() action so that rather than using the pylons.middleware.error_document_template HTML string as a template, it uses your own template:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def document(self):
    my_template="""
    <html>
    <head><title>Error %(code)s</title></head>
    <body>
    <h1>Error %(code)s</h1>
    <p>%(message)s</p>
    </body>
    </html>
    """ % {'code':request.GET('code', ''), 'message':request.GET('message', '')}
    return my_template

The other actions in the default ErrorController are most likely unnecessary when using a customized template. They serve images and style sheets from the Pylons package, for use by Pylons' error_document_template, without the need for those files to be located in your application's public directory.

Changing the error mapper

By default the status codes 404, 500, 401 and 403 are intercepted and redirected to the error controller. This is done by the error mapper specified in the error documents middleware. Have a look at your config/middleware.py file:

1
2
3
# Display error documents for 401, 403, 404 status codes (if debug is disabled also
# intercepts 500)
app = ErrorDocuments(app, global_conf, mapper=error_mapper, **app_conf)

By default the pylons.middleware.error_mapper is used. It looks like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from urllib import urlencode
from paste.deploy.converters import asbool

def error_mapper(code, message, environ, global_conf=None, **kw):
    if environ.get('pylons.error_call'):
        return None
    else:
        environ['pylons.error_call'] = True

    if global_conf is None:
        global_conf = {}
    codes = [401, 403, 404]
    if not asbool(global_conf.get('debug')):
        codes.append(500)
    if code in codes:
        # StatusBasedForward expects a relative URL (no SCRIPT_NAME)
        url = '/error/document/?%s' % (urllib.urlencode({'message': message,
                                                         'code': code}))
        return url

Note how in debug mode the mapper does not intercept server error 500 codes as they are used for the error report produced by the PylonsEvalException middleware.

You can create your own error mapper based on this one to intercept different status codes by changing the line if code in [401, 403, 404, 500]. You can even change the URL so that a static file is served from your public directory rather than by the error controller. Just specify your error_mapper as the mapper parameter to middleware.

Testing Your Error Document

You can test your error document implementation by aborting a request with abort(). The method takes two parameters: the first is an integer representing the error code, the second is the response message to send as part of the status HTTP header.

Add a controller to your project named error_doc_test:

1
$ paster controller error_doc_test

Modify your controller's index() action to look like this:

1
2
def index(self):
    abort(500, 'Internal Server Error')

Then start your server as described in the Getting Started Guide and visit http://localhost:5000/error_doc_test/

You should see the error 500 page with an Internal Server Error message.

Site running on a free Atlassian Confluence Open Source Project License granted to Pylons. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.3.3 Build:#645 Feb 13, 2007) - Bug/feature request - Contact Administrators
Top