- DocString'ed pecan.middleware.errordocument.py - Wrote a Custom Errors Cookbook - Fixed a bug in base config.py scaffold
3.7 KiB
Custom Error Documents
In this article we will configure a Pecan application to display a
custom Error page whenever the server returns
404 Page not Found status.
This article assumes that you have already created a test application
as described in quick_start
Note
While this example focuses on the HTTP 404 status
message, the same technique may be applied to define custom actions for
any of the HTTP status response codes in the 400 and 500
range. You are well advised to use this power judiciously.
Overview
Pecan makes it simple to customize error documents in two simple steps:
configureof the HTTP status messages you want to handle in your application's config.pycontrollersto handle the status messages you have configured
Configure Routing
Let's configure our application test_project to route the
HTTP 404 (page not found) messages to our custom built
controller.
First, we tweak test_project/config.py:
# Pecan Application Configurations
app = {
'root' : 'test_project.controllers.root.RootController',
'modules' : ['test_project'],
'static_root' : '%(confdir)s/public',
'template_path' : '%(confdir)s/test_project/templates',
'reload' : True,
'debug' : True,
## modify the 'errors' element to direct HTTP status codes to your
## own controller.
'errors' : {
#404 : '/error/404',
404 : '/notfound',
'__force_dict__' : True
}
}
Instead of the default error page, Pecan will now route 404 messages to our very own controller named notfound.
Let us now implement the notfound Controller
Write Custom Controllers
The easiest way to implement our custom notfound error
controller is to add it to test_project.root.RootController
class (typically in test_project/controllers/root.py):
from pecan import expose
from webob.exc import status_map
class RootController(object):
@expose(generic=True, template='index.html')
def index(self):
return dict()
@index.when(method='POST')
def index_post(self, q):
redirect('http://pecan.readthedocs.org/en/latest/search.html?q=%s' % q)
## custom handling of '404 Page Not Found' messages
@expose('error.html')
def notfound(self):
return dict(status=404, message="test_project does not have this page")
@expose('error.html')
def error(self, status):
try:
status = int(status)
except ValueError:
status = 0
message = getattr(status_map.get(status), 'explanation', '')
return dict(status=status, message=message)
And that's it!
Notice that the only bit of code we added to our RootController is:
## custom handling of '404 Page Not Found' messages
@expose('error.html')
def notfound(self):
return dict(status=404, message="test_project does not have this page")
We simply @expose the notfound controller
with the error.html template (which was conveniently
generated for us and placed under test_project/templates/ when we
created test_project). As with any common controller
@expose'd through a template, we return a dictionary of
variables for interpolation by the template renderer.
Now we can modify the error template, or write a brand new one to
make the 404 error status page or test_project as pretty or
fancy as we want.