As per [their blog post of the 27th April](https://blog.readthedocs.com/securing-subdomains/) ‘Securing subdomains’: > Starting today, Read the Docs will start hosting projects from subdomains on the domain readthedocs.io, instead of on readthedocs.org. This change addresses some security concerns around site cookies while hosting user generated data on the same domain as our dashboard. Test Plan: Manually visited all the links I’ve modified.
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.
|