120 lines
3.7 KiB
ReStructuredText
120 lines
3.7 KiB
ReStructuredText
.. _errors:
|
|
|
|
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 :ref:`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:
|
|
|
|
Overview
|
|
--------
|
|
|
|
Pecan makes it simple to customize error documents in two simple steps:
|
|
|
|
* :ref:`configure` of the HTTP status messages you want to handle
|
|
in your application's ``config.py``
|
|
* :ref:`controllers` to handle the status messages you have configured
|
|
|
|
.. _configure:
|
|
|
|
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``.
|
|
|
|
.. _controllers:
|
|
|
|
Write Custom Controllers
|
|
------------------------
|
|
|
|
The easiest way to implement the error handler is to
|
|
add it to :class:`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 :class:`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 :func:`~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.
|