Skip to content

Commit 907ce67

Browse files
committed
Merge branch '2.5'
* 2.5: Improve cookbook entry for error pages in 2.3~
2 parents 3b6d6d6 + d618fd0 commit 907ce67

File tree

1 file changed

+209
-76
lines changed

1 file changed

+209
-76
lines changed

cookbook/controller/error_pages.rst

Lines changed: 209 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,100 @@
55
How to Customize Error Pages
66
============================
77

8-
When any exception is thrown in Symfony, the exception is caught inside the
9-
``Kernel`` class and eventually forwarded to a special controller,
10-
``TwigBundle:Exception:show`` for handling. This controller, which lives
11-
inside the core TwigBundle, determines which error template to display and
12-
the status code that should be set for the given exception.
8+
When an exception is thrown, the core ``HttpKernel`` class catches it and
9+
dispatches a ``kernel.exception`` event. This gives you the power to convert
10+
the exception into a ``Response`` in a few different ways.
1311

14-
Error pages can be customized in two different ways, depending on how much
15-
control you need:
12+
The core TwigBundle sets up a listener for this event which will run
13+
a configurable (but otherwise arbitrary) controller to generate the
14+
response. The default controller used has a sensible way of
15+
picking one out of the available set of error templates.
1616

17-
1. Customize the error templates of the different error pages;
17+
Thus, error pages can be customized in different ways, depending on how
18+
much control you need:
1819

19-
2. Replace the default exception controller ``twig.controller.exception:showAction``.
20+
#. :ref:`Use the default ExceptionController and create a few
21+
templates that allow you to customize how your different error
22+
pages look (easy); <use-default-exception-controller>`
2023

21-
The default ExceptionController
22-
-------------------------------
24+
#. :ref:`Replace the default exception controller with your own
25+
(intermediate). <custom-exception-controller>`
2326

24-
The default ``ExceptionController`` will either display an
27+
#. :ref:`Use the kernel.exception event to come up with your own
28+
handling (advanced). <use-kernel-exception-event>`
29+
30+
.. _use-default-exception-controller:
31+
32+
Using the Default ExceptionController
33+
-------------------------------------
34+
35+
By default, the ``showAction()`` method of the
36+
:class:`Symfony\\Bundle\\TwigBundle\\Controller\\ExceptionController`
37+
will be called when an exception occurs.
38+
39+
This controller will either display an
2540
*exception* or *error* page, depending on the setting of the ``kernel.debug``
2641
flag. While *exception* pages give you a lot of helpful
2742
information during development, *error* pages are meant to be
28-
shown to the end-user.
43+
shown to the user in production.
2944

3045
.. sidebar:: Testing Error Pages during Development
3146

3247
You should not set ``kernel.debug`` to ``false`` in order to see your
33-
error pages during development. This will also stop
48+
*error* pages during development. This will also stop
3449
Symfony from recompiling your twig templates, among other things.
3550

3651
The third-party `WebfactoryExceptionsBundle`_ provides a special
3752
test controller that allows you to display your custom error
3853
pages for arbitrary HTTP status codes even with
3954
``kernel.debug`` set to ``true``.
4055

41-
Override Error Templates
42-
------------------------
56+
.. _`WebfactoryExceptionsBundle`: https://github.com/webfactory/exceptions-bundle
57+
58+
.. _cookbook-error-pages-by-status-code:
59+
60+
How the Template for the Error and Exception Pages Is Selected
61+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4362

44-
All of the error templates live inside the TwigBundle. To override the
45-
templates, simply rely on the standard method for overriding templates that
46-
live inside a bundle. For more information, see
47-
:ref:`overriding-bundle-templates`.
63+
The TwigBundle contains some default templates for error and
64+
exception pages in its ``Resources/views/Exception`` directory.
65+
66+
.. tip::
67+
68+
In a standard Symfony installation, the TwigBundle can be found at
69+
``vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle``. In addition
70+
to the standard HTML error page, it also provides a default
71+
error page for many of the most common response formats, including
72+
JSON (``error.json.twig``), XML (``error.xml.twig``) and even
73+
JavaScript (``error.js.twig``), to name a few.
74+
75+
Here is how the ``ExceptionController`` will pick one of the
76+
available templates based on the HTTP status code and request format:
77+
78+
* For *error* pages, it first looks for a template for the given format
79+
and status code (like ``error404.json.twig``);
80+
81+
* If that does not exist or apply, it looks for a general template for
82+
the given format (like ``error.json.twig`` or
83+
``exception.json.twig``);
84+
85+
* Finally, it ignores the format and falls back to the HTML template
86+
(like ``error.html.twig`` or ``exception.html.twig``).
87+
88+
.. tip::
89+
90+
If the exception being handled implements the
91+
:class:`Symfony\\Component\\HttpKernel\\Exception\\HttpExceptionInterface`,
92+
the ``getStatusCode()`` method will be
93+
called to obtain the HTTP status code to use. Otherwise,
94+
the status code will be "500".
95+
96+
Overriding or Adding Templates
97+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
98+
99+
To override these templates, simply rely on the standard method for
100+
overriding templates that live inside a bundle. For more information,
101+
see :ref:`overriding-bundle-templates`.
48102

49103
For example, to override the default error template, create a new
50104
template located at
@@ -74,82 +128,161 @@ template located at
74128

75129
.. tip::
76130

77-
If you're not familiar with Twig, don't worry. Twig is a simple, powerful
78-
and optional templating engine that integrates with Symfony. For more
79-
information about Twig see :doc:`/book/templating`.
131+
If you're not familiar with Twig, don't worry. Twig is a simple,
132+
powerful and optional templating engine that integrates with
133+
Symfony. For more information about Twig see :doc:`/book/templating`.
80134

81-
In addition to the standard HTML error page, Symfony provides a default error
82-
page for many of the most common response formats, including JSON
83-
(``error.json.twig``), XML (``error.xml.twig``) and even JavaScript
84-
(``error.js.twig``), to name a few. To override any of these templates, just
85-
create a new file with the same name in the
86-
``app/Resources/TwigBundle/views/Exception`` directory. This is the standard
87-
way of overriding any template that lives inside a bundle.
135+
This works not only to replace the default templates, but also to add
136+
new ones.
88137

89-
.. _cookbook-error-pages-by-status-code:
138+
For instance, create an ``app/Resources/TwigBundle/views/Exception/error404.html.twig``
139+
template to display a special page for 404 (page not found) errors.
140+
Refer to the previous section for the order in which the
141+
``ExceptionController`` tries different template names.
90142

91-
Customizing the 404 Page and other Error Pages
92-
----------------------------------------------
143+
.. tip::
93144

94-
You can also customize specific error templates according to the HTTP status
95-
code. For instance, create a
96-
``app/Resources/TwigBundle/views/Exception/error404.html.twig`` template to
97-
display a special page for 404 (page not found) errors.
145+
Often, the easiest way to customize an error page is to copy it from
146+
the TwigBundle into ``app/Resources/TwigBundle/views/Exception`` and
147+
then modify it.
98148

99-
Symfony uses the following algorithm to determine which template to use:
149+
.. note::
100150

101-
* First, it looks for a template for the given format and status code (like
102-
``error404.json.twig``);
151+
The debug-friendly exception pages shown to the developer can even be
152+
customized in the same way by creating templates such as
153+
``exception.html.twig`` for the standard HTML exception page or
154+
``exception.json.twig`` for the JSON exception page.
155+
156+
.. _custom-exception-controller:
103157

104-
* If it does not exist, it looks for a template for the given format (like
105-
``error.json.twig``);
158+
Replacing the Default ExceptionController
159+
------------------------------------------
160+
161+
If you need a little more flexibility beyond just overriding the
162+
template, then you can change the controller that renders the error
163+
page. For example, you might need to pass some additional variables into
164+
your template.
165+
166+
.. caution::
106167

107-
* If it does not exist, it falls back to the HTML template (like
108-
``error.html.twig``).
168+
Make sure you don't lose the exception pages that render the helpful
169+
error messages during development.
170+
171+
To do this, simply create a new controller and set the
172+
:ref:`twig.exception_controller <config-twig-exception-controller>` option
173+
to point to it.
174+
175+
.. configuration-block::
176+
177+
.. code-block:: yaml
178+
179+
# app/config/config.yml
180+
twig:
181+
exception_controller: AcmeFooBundle:Exception:showException
182+
183+
.. code-block:: xml
184+
185+
<!-- app/config/config.xml -->
186+
<?xml version="1.0" encoding="UTF-8" ?>
187+
<container xmlns="http://symfony.com/schema/dic/services"
188+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
189+
xmlns:twig="http://symfony.com/schema/dic/twig"
190+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
191+
http://symfony.com/schema/dic/twig http://symfony.com/schema/dic/twig/twig-1.0.xsd">
192+
193+
<twig:config>
194+
<twig:exception-controller>AcmeFooBundle:Exception:showException</twig:exception-controller>
195+
</twig:config>
196+
</container>
197+
198+
.. code-block:: php
199+
200+
// app/config/config.php
201+
$container->loadFromExtension('twig', array(
202+
'exception_controller' => 'AcmeFooBundle:Exception:showException',
203+
// ...
204+
));
109205
110206
.. tip::
111207

112-
To see the full list of default error templates, see the
113-
``Resources/views/Exception`` directory of the TwigBundle. In a
114-
standard Symfony installation, the TwigBundle can be found at
115-
``vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle``. Often, the easiest way
116-
to customize an error page is to copy it from the TwigBundle into
117-
``app/Resources/TwigBundle/views/Exception`` and then modify it.
208+
You can also set up your controller as a service.
118209

119-
.. note::
210+
The default value of ``twig.controller.exception:showAction`` refers
211+
to the ``showAction`` method of the ``ExceptionController``
212+
described previously, which is registered in the DIC as the
213+
``twig.controller.exception`` service.
120214

121-
The debug-friendly exception pages shown to the developer can even be
122-
customized in the same way by creating templates such as
123-
``exception.html.twig`` for the standard HTML exception page or
124-
``exception.json.twig`` for the JSON exception page.
215+
Your controller will be passed two parameters: ``exception``,
216+
which is a :class:`\\Symfony\\Component\\Debug\\Exception\\FlattenException`
217+
instance created from the exception being handled, and ``logger``,
218+
an instance of :class:`\\Symfony\\Component\\HttpKernel\\Log\\DebugLoggerInterface`
219+
(which may be ``null``).
125220

126-
.. _`WebfactoryExceptionsBundle`: https://github.com/webfactory/exceptions-bundle
221+
.. tip::
127222

128-
Replace the default Exception Controller
129-
----------------------------------------
223+
The Request that will be dispatched to your controller is created
224+
in the :class:`Symfony\\Component\\HttpKernel\\EventListener\\ExceptionListener`.
225+
This event listener is set up by the TwigBundle.
130226

131-
If you need a little more flexibility beyond just overriding the template
132-
(e.g. you need to pass some additional variables into your template),
133-
then you can override the controller that renders the error page.
227+
You can, of course, also extend the previously described
228+
:class:`Symfony\\Bundle\\TwigBundle\\Controller\\ExceptionController`.
229+
In that case, you might want to override one or both of the
230+
``showAction`` and ``findTemplate`` methods. The latter one locates the
231+
template to be used.
134232

135-
The default exception controller is registered as a service - the actual
136-
class is ``Symfony\Bundle\TwigBundle\Controller\ExceptionController``.
233+
.. caution::
137234

138-
To do this, create a new controller class and make it extend Symfony's default
139-
``Symfony\Bundle\TwigBundle\Controller\ExceptionController`` class.
235+
As of writing, the ``ExceptionController`` is *not* part of the
236+
Symfony API, so be aware that it might change in following releases.
140237

141-
There are several methods you can override to customize different parts of how
142-
the error page is rendered. You could, for example, override the entire
143-
``showAction`` or just the ``findTemplate`` method, which locates which
144-
template should be rendered.
238+
.. _use-kernel-exception-event:
145239

146-
To make Symfony use your exception controller instead of the default, set the
147-
:ref:`twig.exception_controller <config-twig-exception-controller>` option
148-
in app/config/config.yml.
240+
Working with the kernel.exception Event
241+
-----------------------------------------
242+
243+
As mentioned in the beginning, the ``kernel.exception`` event is
244+
dispatched whenever the Symfony Kernel needs to
245+
handle an exception. For more information on that, see :ref:`kernel-kernel.exception`.
246+
247+
Working with this event is actually much more powerful than what has
248+
been explained before but also requires a thorough understanding of
249+
Symfony internals.
250+
251+
To give one example, assume your application throws
252+
specialized exceptions with a particular meaning to your domain.
253+
254+
In that case, all the default ``ExceptionListener`` and
255+
``ExceptionController`` could do for you was trying to figure out the
256+
right HTTP status code and display your nice-looking error page.
257+
258+
:doc:`Writing your own event listener </cookbook/service_container/event_listener>`
259+
for the ``kernel.exception`` event allows you to have a closer look
260+
at the exception and take different actions depending on it. Those
261+
actions might include logging the exception, redirecting the user to
262+
another page or rendering specialized error pages.
263+
264+
.. note::
265+
266+
If your listener calls ``setResponse()`` on the
267+
:class:`Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent`,
268+
event propagation will be stopped and the response will be sent to
269+
the client.
270+
271+
This approach allows you to create centralized and layered error
272+
handling: Instead of catching (and handling) the same exceptions
273+
in various controllers again and again, you can have just one (or
274+
several) listeners deal with them.
149275

150276
.. tip::
151277

152-
The customization of exception handling is actually much more powerful
153-
than what's written here. An internal event, ``kernel.exception``, is thrown
154-
which allows complete control over exception handling. For more
155-
information, see :ref:`kernel-kernel.exception`.
278+
To see an example, have a look at the `ExceptionListener`_ in the
279+
Security Component.
280+
281+
It handles various security-related exceptions that are thrown in
282+
your application (like :class:`Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException`)
283+
and takes measures like redirecting the user to the login page,
284+
logging them out and other things.
285+
286+
Good luck!
287+
288+
.. _`ExceptionListener`: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy