deb-python-pecan/docs/source/errors.rst

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.