diff --git a/cookbook/controller/error_pages.rst b/cookbook/controller/error_pages.rst index 00cb1b420f8..fa8efef21fc 100644 --- a/cookbook/controller/error_pages.rst +++ b/cookbook/controller/error_pages.rst @@ -5,32 +5,47 @@ How to Customize Error Pages ============================ -When any exception is thrown in Symfony, the exception is caught inside the -``Kernel`` class and eventually forwarded to a special controller, -``TwigBundle:Exception:show`` for handling. This controller, which lives -inside the core TwigBundle, determines which error template to display and -the status code that should be set for the given exception. +When an exception is thrown, the core ``HttpKernel`` class catches it and +dispatches a ``kernel.exception`` event. This gives you the power to convert +the exception into a ``Response`` in a few different ways. -Error pages can be customized in two different ways, depending on how much -control you need: +The core TwigBundle sets up a listener for this event which will run +a configurable (but otherwise arbitrary) controller to generate the +response. The default controller used has a sensible way of +picking one out of the available set of error templates. -1. Customize the error templates of the different error pages; +Thus, error pages can be customized in different ways, depending on how +much control you need: -2. Replace the default exception controller ``twig.controller.exception:showAction``. +#. :ref:`Use the default ExceptionController and create a few + templates that allow you to customize how your different error + pages look (easy); ` -The default ExceptionController -------------------------------- +#. :ref:`Replace the default exception controller with your own + (intermediate). ` -The default ``ExceptionController`` will either display an +#. :ref:`Use the kernel.exception event to come up with your own + handling (advanced). ` + +.. _use-default-exception-controller: + +Using the Default ExceptionController +------------------------------------- + +By default, the ``showAction()`` method of the +:class:`Symfony\\Bundle\\TwigBundle\\Controller\\ExceptionController` +will be called when an exception occurs. + +This controller will either display an *exception* or *error* page, depending on the setting of the ``kernel.debug`` flag. While *exception* pages give you a lot of helpful information during development, *error* pages are meant to be -shown to the end-user. +shown to the user in production. .. sidebar:: Testing Error Pages during Development You should not set ``kernel.debug`` to ``false`` in order to see your - error pages during development. This will also stop + *error* pages during development. This will also stop Symfony from recompiling your twig templates, among other things. The third-party `WebfactoryExceptionsBundle`_ provides a special @@ -38,13 +53,52 @@ shown to the end-user. pages for arbitrary HTTP status codes even with ``kernel.debug`` set to ``true``. -Override Error Templates ------------------------- +.. _`WebfactoryExceptionsBundle`: https://github.com/webfactory/exceptions-bundle + +.. _cookbook-error-pages-by-status-code: + +How the Template for the Error and Exception Pages Is Selected +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -All of the error templates live inside the TwigBundle. To override the -templates, simply rely on the standard method for overriding templates that -live inside a bundle. For more information, see -:ref:`overriding-bundle-templates`. +The TwigBundle contains some default templates for error and +exception pages in its ``Resources/views/Exception`` directory. + +.. tip:: + + In a standard Symfony installation, the TwigBundle can be found at + ``vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle``. In addition + to the standard HTML error page, it also provides a default + error page for many of the most common response formats, including + JSON (``error.json.twig``), XML (``error.xml.twig``) and even + JavaScript (``error.js.twig``), to name a few. + +Here is how the ``ExceptionController`` will pick one of the +available templates based on the HTTP status code and request format: + +* For *error* pages, it first looks for a template for the given format + and status code (like ``error404.json.twig``); + +* If that does not exist or apply, it looks for a general template for + the given format (like ``error.json.twig`` or + ``exception.json.twig``); + +* Finally, it ignores the format and falls back to the HTML template + (like ``error.html.twig`` or ``exception.html.twig``). + +.. tip:: + + If the exception being handled implements the + :class:`Symfony\\Component\\HttpKernel\\Exception\\HttpExceptionInterface`, + the ``getStatusCode()`` method will be + called to obtain the HTTP status code to use. Otherwise, + the status code will be "500". + +Overriding or Adding Templates +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To override these templates, simply rely on the standard method for +overriding templates that live inside a bundle. For more information, +see :ref:`overriding-bundle-templates`. For example, to override the default error template, create a new template located at @@ -74,82 +128,161 @@ template located at .. tip:: - If you're not familiar with Twig, don't worry. Twig is a simple, powerful - and optional templating engine that integrates with Symfony. For more - information about Twig see :doc:`/book/templating`. + If you're not familiar with Twig, don't worry. Twig is a simple, + powerful and optional templating engine that integrates with + Symfony. For more information about Twig see :doc:`/book/templating`. -In addition to the standard HTML error page, Symfony provides a default error -page for many of the most common response formats, including JSON -(``error.json.twig``), XML (``error.xml.twig``) and even JavaScript -(``error.js.twig``), to name a few. To override any of these templates, just -create a new file with the same name in the -``app/Resources/TwigBundle/views/Exception`` directory. This is the standard -way of overriding any template that lives inside a bundle. +This works not only to replace the default templates, but also to add +new ones. -.. _cookbook-error-pages-by-status-code: +For instance, create an ``app/Resources/TwigBundle/views/Exception/error404.html.twig`` +template to display a special page for 404 (page not found) errors. +Refer to the previous section for the order in which the +``ExceptionController`` tries different template names. -Customizing the 404 Page and other Error Pages ----------------------------------------------- +.. tip:: -You can also customize specific error templates according to the HTTP status -code. For instance, create a -``app/Resources/TwigBundle/views/Exception/error404.html.twig`` template to -display a special page for 404 (page not found) errors. + Often, the easiest way to customize an error page is to copy it from + the TwigBundle into ``app/Resources/TwigBundle/views/Exception`` and + then modify it. -Symfony uses the following algorithm to determine which template to use: +.. note:: -* First, it looks for a template for the given format and status code (like - ``error404.json.twig``); + The debug-friendly exception pages shown to the developer can even be + customized in the same way by creating templates such as + ``exception.html.twig`` for the standard HTML exception page or + ``exception.json.twig`` for the JSON exception page. + +.. _custom-exception-controller: -* If it does not exist, it looks for a template for the given format (like - ``error.json.twig``); +Replacing the Default ExceptionController +------------------------------------------ + +If you need a little more flexibility beyond just overriding the +template, then you can change the controller that renders the error +page. For example, you might need to pass some additional variables into +your template. + +.. caution:: -* If it does not exist, it falls back to the HTML template (like - ``error.html.twig``). + Make sure you don't lose the exception pages that render the helpful + error messages during development. + +To do this, simply create a new controller and set the +:ref:`twig.exception_controller ` option +to point to it. + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/config.yml + twig: + exception_controller: AcmeFooBundle:Exception:showException + + .. code-block:: xml + + + + + + + AcmeFooBundle:Exception:showException + + + + .. code-block:: php + + // app/config/config.php + $container->loadFromExtension('twig', array( + 'exception_controller' => 'AcmeFooBundle:Exception:showException', + // ... + )); .. tip:: - To see the full list of default error templates, see the - ``Resources/views/Exception`` directory of the TwigBundle. In a - standard Symfony installation, the TwigBundle can be found at - ``vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle``. Often, the easiest way - to customize an error page is to copy it from the TwigBundle into - ``app/Resources/TwigBundle/views/Exception`` and then modify it. + You can also set up your controller as a service. -.. note:: + The default value of ``twig.controller.exception:showAction`` refers + to the ``showAction`` method of the ``ExceptionController`` + described previously, which is registered in the DIC as the + ``twig.controller.exception`` service. - The debug-friendly exception pages shown to the developer can even be - customized in the same way by creating templates such as - ``exception.html.twig`` for the standard HTML exception page or - ``exception.json.twig`` for the JSON exception page. +Your controller will be passed two parameters: ``exception``, +which is a :class:`\\Symfony\\Component\\Debug\\Exception\\FlattenException` +instance created from the exception being handled, and ``logger``, +an instance of :class:`\\Symfony\\Component\\HttpKernel\\Log\\DebugLoggerInterface` +(which may be ``null``). -.. _`WebfactoryExceptionsBundle`: https://github.com/webfactory/exceptions-bundle +.. tip:: -Replace the default Exception Controller ----------------------------------------- + The Request that will be dispatched to your controller is created + in the :class:`Symfony\\Component\\HttpKernel\\EventListener\\ExceptionListener`. + This event listener is set up by the TwigBundle. -If you need a little more flexibility beyond just overriding the template -(e.g. you need to pass some additional variables into your template), -then you can override the controller that renders the error page. +You can, of course, also extend the previously described +:class:`Symfony\\Bundle\\TwigBundle\\Controller\\ExceptionController`. +In that case, you might want to override one or both of the +``showAction`` and ``findTemplate`` methods. The latter one locates the +template to be used. -The default exception controller is registered as a service - the actual -class is ``Symfony\Bundle\TwigBundle\Controller\ExceptionController``. +.. caution:: -To do this, create a new controller class and make it extend Symfony's default -``Symfony\Bundle\TwigBundle\Controller\ExceptionController`` class. + As of writing, the ``ExceptionController`` is *not* part of the + Symfony API, so be aware that it might change in following releases. -There are several methods you can override to customize different parts of how -the error page is rendered. You could, for example, override the entire -``showAction`` or just the ``findTemplate`` method, which locates which -template should be rendered. +.. _use-kernel-exception-event: -To make Symfony use your exception controller instead of the default, set the -:ref:`twig.exception_controller ` option -in app/config/config.yml. +Working with the kernel.exception Event +----------------------------------------- + +As mentioned in the beginning, the ``kernel.exception`` event is +dispatched whenever the Symfony Kernel needs to +handle an exception. For more information on that, see :ref:`kernel-kernel.exception`. + +Working with this event is actually much more powerful than what has +been explained before but also requires a thorough understanding of +Symfony internals. + +To give one example, assume your application throws +specialized exceptions with a particular meaning to your domain. + +In that case, all the default ``ExceptionListener`` and +``ExceptionController`` could do for you was trying to figure out the +right HTTP status code and display your nice-looking error page. + +:doc:`Writing your own event listener ` +for the ``kernel.exception`` event allows you to have a closer look +at the exception and take different actions depending on it. Those +actions might include logging the exception, redirecting the user to +another page or rendering specialized error pages. + +.. note:: + + If your listener calls ``setResponse()`` on the + :class:`Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent`, + event propagation will be stopped and the response will be sent to + the client. + +This approach allows you to create centralized and layered error +handling: Instead of catching (and handling) the same exceptions +in various controllers again and again, you can have just one (or +several) listeners deal with them. .. tip:: - The customization of exception handling is actually much more powerful - than what's written here. An internal event, ``kernel.exception``, is thrown - which allows complete control over exception handling. For more - information, see :ref:`kernel-kernel.exception`. + To see an example, have a look at the `ExceptionListener`_ in the + Security Component. + + It handles various security-related exceptions that are thrown in + your application (like :class:`Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException`) + and takes measures like redirecting the user to the login page, + logging them out and other things. + +Good luck! + +.. _`ExceptionListener`: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php 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