Skip to content

Commit 891b677

Browse files
committed
minor #12687 Fix 12273 Added new ErrorController (dbrekelmans)
This PR was squashed before being merged into the 4.4 branch (closes #12687). Discussion ---------- Fix 12273 Added new ErrorController Partially fixes #12273 The `Overriding the Default ErrorController` paragraph in `controller/error_pages.rst` still needs to be updated. I struggled with this so I would really appreciate if someone else could step in and finish that paragraph! For further reference, see #12273 (comment) Commits ------- 4c867f9 Fix 12273 Added new ErrorController
2 parents ddc05a6 + 4c867f9 commit 891b677

File tree

3 files changed

+101
-60
lines changed

3 files changed

+101
-60
lines changed

controller/error_pages.rst

+77-60
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,6 @@ In Symfony applications, all errors are treated as exceptions, no matter if they
99
are just a 404 Not Found error or a fatal error triggered by throwing some
1010
exception in your code.
1111

12-
If your app has the `TwigBundle`_ installed, a special controller handles these
13-
exceptions. This controller displays debug information for errors and allows to
14-
customize error pages, so run this command to make sure the bundle is installed:
15-
16-
.. code-block:: terminal
17-
18-
$ composer require twig
19-
2012
In the :ref:`development environment <configuration-environments>`,
2113
Symfony catches all the exceptions and displays a special **exception page**
2214
with lots of debug information to help you discover the root problem:
@@ -39,45 +31,50 @@ Error pages for the production environment can be customized in different ways
3931
depending on your needs:
4032

4133
#. If you just want to change the contents and styles of the error pages to match
42-
the rest of your application, :ref:`override the default error templates <use-default-exception-controller>`;
34+
the rest of your application, :ref:`override the default error templates <use-default-error-controller>`;
35+
36+
#. If you want to change the contents of non-HTML error output, :ref:`create a new normalizer <overriding-non-html-error-output>`;
4337

4438
#. If you also want to tweak the logic used by Symfony to generate error pages,
45-
:ref:`override the default exception controller <custom-exception-controller>`;
39+
:ref:`override the default error controller <custom-error-controller>`;
4640

4741
#. If you need total control of exception handling to execute your own logic
4842
:ref:`use the kernel.exception event <use-kernel-exception-event>`.
4943

50-
.. _use-default-exception-controller:
51-
.. _using-the-default-exceptioncontroller:
44+
.. _use-default-error-controller:
45+
.. _using-the-default-errorcontroller:
5246

5347
Overriding the Default Error Templates
5448
--------------------------------------
5549

56-
When the error page loads, an internal :class:`Symfony\\Bundle\\TwigBundle\\Controller\\ExceptionController`
50+
You can use the built-in Twig error renderer to easily override the default error templates.
51+
Both the TwigBundle and TwigBridge need to be installed for this.
52+
Run this command to ensure both are installed:
53+
54+
.. code-block:: terminal
55+
56+
$ composer require twig
57+
58+
When the error page loads, :class:`Symfony\\Bridge\\Twig\\ErrorRenderer\\TwigErrorRenderer`
5759
is used to render a Twig template to show the user.
5860

5961
.. _controller-error-pages-by-status-code:
6062

61-
This controller uses the HTTP status code, the request format and the following
63+
This renderer uses the HTTP status code and the following
6264
logic to determine the template filename:
6365

64-
#. Look for a template for the given format and status code (like ``error404.json.twig``
65-
or ``error500.html.twig``);
66+
#. Look for a template for the given status code (like ``error500.html.twig``);
6667

6768
#. If the previous template doesn't exist, discard the status code and look for
68-
a generic template for the given format (like ``error.json.twig`` or
69-
``error.xml.twig``);
70-
71-
#. If none of the previous templates exist, fall back to the generic HTML template
72-
(``error.html.twig``).
69+
a generic error template (``error.html.twig``).
7370

7471
.. _overriding-or-adding-templates:
7572

7673
To override these templates, rely on the standard Symfony method for
7774
:ref:`overriding templates that live inside a bundle <override-templates>` and
7875
put them in the ``templates/bundles/TwigBundle/Exception/`` directory.
7976

80-
A typical project that returns HTML and JSON pages might look like this:
77+
A typical project that returns HTML pages might look like this:
8178

8279
.. code-block:: text
8380
@@ -87,10 +84,7 @@ A typical project that returns HTML and JSON pages might look like this:
8784
└─ Exception/
8885
├─ error404.html.twig
8986
├─ error403.html.twig
90-
├─ error.html.twig # All other HTML errors (including 500)
91-
├─ error404.json.twig
92-
├─ error403.json.twig
93-
└─ error.json.twig # All other JSON errors (including 500)
87+
└─ error.html.twig # All other HTML errors (including 500)
9488
9589
Example 404 Error Template
9690
--------------------------
@@ -112,24 +106,17 @@ To override the 404 error template for HTML pages, create a new
112106
</p>
113107
{% endblock %}
114108

115-
In case you need them, the ``ExceptionController`` passes some information to
109+
In case you need them, the ``TwigErrorRenderer`` passes some information to
116110
the error template via the ``status_code`` and ``status_text`` variables that
117111
store the HTTP status code and message respectively.
118112

119113
.. tip::
120114

121-
You can customize the status code by implementing
115+
You can customize the status code of an exception by implementing
122116
:class:`Symfony\\Component\\HttpKernel\\Exception\\HttpExceptionInterface`
123117
and its required ``getStatusCode()`` method. Otherwise, the ``status_code``
124118
will default to ``500``.
125119

126-
.. note::
127-
128-
The exception pages shown in the development environment can be customized
129-
in the same way as error pages. Create a new ``exception.html.twig`` template
130-
for the standard HTML exception page or ``exception.json.twig`` for the JSON
131-
exception page.
132-
133120
Security & 404 Pages
134121
--------------------
135122

@@ -146,12 +133,12 @@ While you're in the development environment, Symfony shows the big *exception*
146133
page instead of your shiny new customized error page. So, how can you see
147134
what it looks like and debug it?
148135

149-
Fortunately, the default ``ExceptionController`` allows you to preview your
136+
Fortunately, the default ``ErrorController`` allows you to preview your
150137
*error* pages during development.
151138

152-
To use this feature, you need to load some special routes provided by TwigBundle
139+
To use this feature, you need to load some special routes provided by FrameworkBundle
153140
(if the application uses :ref:`Symfony Flex <symfony-flex>` they are loaded
154-
automatically when installing Twig support):
141+
automatically when installing ``symfony/framework-bundle``):
155142

156143
.. configuration-block::
157144

@@ -193,56 +180,88 @@ for a given status code as HTML or for a given status code and format.
193180
http://localhost/index.php/_error/{statusCode}
194181
http://localhost/index.php/_error/{statusCode}.{format}
195182
196-
.. _custom-exception-controller:
197-
.. _replacing-the-default-exceptioncontroller:
183+
.. _overriding-non-html-error-output:
184+
185+
Overriding Error output for non-HTML formats
186+
--------------------------------------------
198187

199-
Overriding the Default ExceptionController
200-
------------------------------------------
188+
To override non-HTML error output, the Serializer component needs to be installed.
189+
190+
.. code-block:: terminal
191+
192+
$ composer require serializer
193+
194+
The Serializer component has a built-in ``FlattenException`` normalizer (``ProblemNormalizer``) and JSON/XML/CSV/YAML
195+
encoders by default. That means that if an exception were to be thrown in your application, Symfony can output it in
196+
a format supported by one of the encoders. If you want to change how the output is structured, all you have to do
197+
is create a new Normalizer that supports the ``FlattenException`` input::
198+
199+
class MyCustomProblemNormalizer implements NormalizerInterface
200+
{
201+
public function normalize($exception, $format = null, array $context = [])
202+
{
203+
return [
204+
'content': 'This is my custom problem normalizer.',
205+
'exception': [
206+
'message': $exception->getMessage(),
207+
'code': $exception->getStatusCode(),
208+
],
209+
];
210+
}
211+
212+
public function supportsNormalization($data, $format = null)
213+
{
214+
return $data instanceof FlattenException;
215+
}
216+
}
217+
218+
.. _custom-error-controller:
219+
.. _replacing-the-default-errorcontroller:
220+
221+
Overriding the Default ErrorController
222+
--------------------------------------
201223

202224
If you need a little more flexibility beyond just overriding the template,
203225
then you can change the controller that renders the error page. For example,
204226
you might need to pass some additional variables into your template.
205227

206228
To do this, create a new controller anywhere in your application and set
207-
the :ref:`twig.exception_controller <config-twig-exception-controller>`
229+
the :ref:`framework.error_controller <config-framework-error_controller>`
208230
configuration option to point to it:
209231

210232
.. configuration-block::
211233

212234
.. code-block:: yaml
213235
214-
# config/packages/twig.yaml
215-
twig:
216-
exception_controller: App\Controller\ExceptionController::showAction
236+
# config/packages/framework.yaml
237+
framework:
238+
error_controller: App\Controller\ErrorController::showAction
217239
218240
.. code-block:: xml
219241
220-
<!-- config/packages/twig.xml -->
242+
<!-- config/packages/framework.xml -->
221243
<?xml version="1.0" encoding="UTF-8" ?>
222244
<container xmlns="http://symfony.com/schema/dic/services"
223245
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
224-
xmlns:twig="http://symfony.com/schema/dic/twig"
225246
xsi:schemaLocation="http://symfony.com/schema/dic/services
226-
https://symfony.com/schema/dic/services/services-1.0.xsd
227-
http://symfony.com/schema/dic/twig
228-
https://symfony.com/schema/dic/twig/twig-1.0.xsd">
247+
https://symfony.com/schema/dic/services/services-1.0.xsd">
229248
230-
<twig:config>
231-
<twig:exception-controller>App\Controller\ExceptionController::showAction</twig:exception-controller>
232-
</twig:config>
249+
<framework:config>
250+
<framework:error_controller>App\Controller\ErrorController::showAction</framework:error_controller>
251+
</framework:config>
233252
234253
</container>
235254
236255
.. code-block:: php
237256
238257
// config/packages/twig.php
239-
$container->loadFromExtension('twig', [
240-
'exception_controller' => 'App\Controller\ExceptionController::showAction',
258+
$container->loadFromExtension('framework', [
259+
'error_controller' => 'App\Controller\ErrorController::showAction',
241260
// ...
242261
]);
243262
244-
The :class:`Symfony\\Component\\HttpKernel\\EventListener\\ExceptionListener`
245-
class used by the TwigBundle as a listener of the ``kernel.exception`` event creates
263+
The :class:`Symfony\\Component\\HttpKernel\\EventListener\\ErrorListener`
264+
class used by the FrameworkBundle as a listener of the ``kernel.exception`` event creates
246265
the request that will be dispatched to your controller. In addition, your controller
247266
will be passed two parameters:
248267

@@ -355,5 +374,3 @@ time and again, you can have just one (or several) listeners deal with them.
355374
your application (like :class:`Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException`)
356375
and takes measures like redirecting the user to the login page, logging them
357376
out and other things.
358-
359-
.. _`TwigBundle`: https://github.com/symfony/twig-bundle

reference/configuration/framework.rst

+18
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Configuration
7474

7575
* `default_locale`_
7676
* `disallow_search_engine_index`_
77+
* `error_controller`_
7778
* `esi`_
7879

7980
* :ref:`enabled <reference-esi-enabled>`
@@ -596,6 +597,23 @@ If you're using forms, but want to avoid starting your session (e.g. using
596597
forms in an API-only website), ``csrf_protection`` will need to be set to
597598
``false``.
598599

600+
.. _config-framework-error_controller:
601+
602+
error_controller
603+
~~~~~~~~~~~~~~~~
604+
605+
**type**: ``string`` **default**: ``error_controller``
606+
607+
.. versionadded:: 4.4
608+
609+
The ``error_controller`` option was introduced in Symfony 4.4.
610+
611+
This is the controller that is activated after an exception is thrown anywhere
612+
in your application. The default controller
613+
(:class:`Symfony\\Component\\HttpKernel\\Controller\\ErrorController`)
614+
is what's responsible for rendering specific templates under different error
615+
conditions (see :doc:`/controller/error_pages`).
616+
599617
esi
600618
~~~
601619

reference/configuration/twig.rst

+6
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,12 @@ exception_controller
203203

204204
**type**: ``string`` **default**: ``twig.controller.exception:showAction``
205205

206+
.. deprecated:: 4.4
207+
208+
The ``exception_controller`` configuration option was deprecated in Symfony 4.4.
209+
Set it to ``null`` and use the new ``error_controller`` option under ``framework``
210+
configuration instead.
211+
206212
This is the controller that is activated after an exception is thrown anywhere
207213
in your application. The default controller
208214
(:class:`Symfony\\Bundle\\TwigBundle\\Controller\\ExceptionController`)

0 commit comments

Comments
 (0)