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 a
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
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:
configure
of the HTTP status messages you want to handle in your application'sconfig.py
controllers
to handle the status messages you have configured
Configure Routing
Let's configure our application test_project
to route
HTTP 404 Page Not Found
messages to a custom
controller.
First, let's update test_project/config.py
to specify a
new error-handler.
# 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' key to direct HTTP status codes to a custom
# controller
'errors' : {
#404 : '/error/404',
404 : '/notfound',
'__force_dict__' : True
}
}
Instead of the default error page, Pecan will now route 404 messages
to the controller method notfound
.
Write Custom Controllers
The easiest way to implement the error handler 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('https://pecan.readthedocs.io/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
was:
## 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 ~pecan.decorators.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 Pecan controller, 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 of test_project
as pretty or
fancy as we want.