Symfony custom error page

In Symfony applications, all errors are treated as exceptions, no matter if they are a 404 Not Found error or a fatal error triggered by throwing some exception in your code.

Edit this page

How to Customize Error Pages

In Symfony applications, all errors are treated as exceptions, no matter if they
are a 404 Not Found error or a fatal error triggered by throwing some exception
in your code.

In the development environment,
Symfony catches all the exceptions and displays a special exception page
with lots of debug information to help you discover the root problem:

A typical exception page in the development environment

Since these pages contain a lot of sensitive internal information, Symfony won’t
display them in the production environment. Instead, it’ll show a minimal and
generic error page:

A typical error page in the production environment

Error pages for the production environment can be customized in different ways
depending on your needs:

  1. If you only want to change the contents and styles of the error pages to match
    the rest of your application, override the default error templates;
  2. If you want to change the contents of non-HTML error output,
    create a new normalizer;
  3. If you also want to tweak the logic used by Symfony to generate error pages,
    override the default error controller;
  4. If you need total control of exception handling to run your own logic
    use the kernel.exception event.

Overriding the Default Error Templates

You can use the built-in Twig error renderer to override the default error
templates. Both the TwigBundle and TwigBridge need to be installed for this. Run
this command to ensure both are installed:

When the error page loads, TwigErrorRenderer
is used to render a Twig template to show the user.

This renderer uses the HTTP status code and the following
logic to determine the template filename:

  1. Look for a template for the given status code (like error500.html.twig);
  2. If the previous template doesn’t exist, discard the status code and look for
    a generic error template (error.html.twig).

To override these templates, rely on the standard Symfony method for
overriding templates that live inside a bundle and
put them in the templates/bundles/TwigBundle/Exception/ directory.

A typical project that returns HTML pages might look like this:

Example 404 Error Template

To override the 404 error template for HTML pages, create a new
error404.html.twig template located at templates/bundles/TwigBundle/Exception/:

In case you need them, the TwigErrorRenderer passes some information to
the error template via the status_code and status_text variables that
store the HTTP status code and message respectively.

Tip

You can customize the status code of an exception by implementing
HttpExceptionInterface
and its required getStatusCode() method. Otherwise, the status_code
will default to 500.

Additionally you have access to the Exception with exception, which for example
allows you to output the stack trace using {{ exception.traceAsString }} or
access any other method on the object. You should be careful with this though,
as this is very likely to expose sensitive data.

Tip

PHP errors are turned into exceptions as well by default, so you can also
access these error details using exception.

Security & 404 Pages

Due to the order of how routing and security are loaded, security information will
not be available on your 404 pages. This means that it will appear as if your
user is logged out on the 404 page (it will work while testing, but not on production).

Testing Error Pages during Development

While you’re in the development environment, Symfony shows the big exception
page instead of your shiny new customized error page. So, how can you see
what it looks like and debug it?

Fortunately, the default ErrorController allows you to preview your
error pages during development.

To use this feature, you need to load some special routes provided by FrameworkBundle
(if the application uses Symfony Flex they are loaded
automatically when installing symfony/framework-bundle):

  • YAML
  • XML
  • PHP

With this route added, you can use URLs like these to preview the error page
for a given status code as HTML or for a given status code and format (you might
need to replace http://localhost/ by the host used in your local setup):

  • http://localhost/_error/{statusCode} for HTML
  • http://localhost/_error/{statusCode}.{format} for any other format

Overriding Error output for non-HTML formats

To override non-HTML error output, the Serializer component needs to be installed.

The Serializer component has a built-in FlattenException normalizer
(ProblemNormalizer) and
JSON/XML/CSV/YAML encoders. When your application throws an exception, Symfony
can output it in one of those formats. If you want to change the output
contents, create a new Normalizer that supports the FlattenException input:

Overriding the Default ErrorController

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.

To do this, create a new controller anywhere in your application and set
the framework.error_controller
configuration option to point to it:

  • YAML
  • XML
  • PHP

The ErrorListener
class used by the FrameworkBundle as a listener of the kernel.exception event creates
the request that will be dispatched to your controller. In addition, your controller
will be passed two parameters:

exception
The original Throwable instance being handled.
logger
A DebugLoggerInterface
instance which may be null in some circumstances.

Working with the kernel.exception Event

When an exception is thrown, the 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.

Working with this event is actually much more powerful than what has been explained
before, but also requires a thorough understanding of Symfony internals. Suppose
that your code throws specialized exceptions with a particular meaning to your
application domain.

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 setThrowable() on the
ExceptionEvent
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
time and again, you can have just one (or several) listeners deal with them.

Tip

See ExceptionListener
class code for a real example of an advanced listener of this type. This
listener handles various security-related exceptions that are thrown in
your application (like AccessDeniedException)
and takes measures like redirecting the user to the login page, logging them
out and other things.

Как настроить страницы ошибок

Дата обновления перевода: 2023-01-18

Как настроить страницы ошибок

В приложениях Symfony все ошибки воспринимаются, как исключения, вне зависимости
от того, являются ли они простой ошибкой 404 «Не найдено» или фатальной ошибкой,
запущенной вызовом какого-то исключения в вашем коде.

В окружении разработки, Symfony ловит все
исключения и отображаеть специальную страницу исключений со множеством информации
по отладке, чтобы помочь вам быстро обнаружить основную проблему:

Типичная страница исключений в окружении разработки

Так как эти страницы содержат много чувствительной внутренней информации, Symfony
не будет отображать её в окружении производства. Вместо этого, она покажет простую
и общую ошибку страница ошибки:

Типичная страница ошибки в окружении производства

Страницы ошибок в окружении производства можно настроить разными способами, в
зависимости от ваших потребностей:

  1. Если вы просто хотите изменить содержание и стили страниц ошибок так, чтобы
    они совпадали с остальным вашим приложением,
    переопределите шаблоны ошибок по умолчанию ;
  2. Если вы хотите изменить содержание вывода ошибки не в HTML,
    создайте новый нормализатор ;
  3. Если вы также хотите настроить логику, используемую Symfony для генерирования ваших
    страниц ошибок, то переопределите контроллер ошибок по умолчанию ;
  4. Если вам нужен полный контроль над работой с исключениями, выполните вашу
    собственную логику — используйте событие the kernel.exception .

Переопределение шаблонов ошибок по умолчанию

Вы можете использовать встроенное средство отображения ошибок Twig, чтобы переопределять
шаблоны ошибок по умолчанию. Для этого должны быть установлены как TwigBundle, так и TwigBridge.
Выполните эту команду, чтобы убедиться, что они оба установлены:

Когда загружается страница ошибки, для отображения шаблона twig и демонастрации
пользователю, используется TwigErrorRenderer.

Этот отображатель использует статус-код HTTP, формат запроса и следующую логику,
чтобы определить имя файла шаблона:

  1. Ищет шаблон для заданного статус-кода (вроде error500.html.twig);
  2. Если предыдущий шаблон не существует, отбросьте статус-код и ищет общий
    шаблон ошибок (error.html.twig).

Чтобы переопределить эти шаблоны, просто положитесь на стандартный метод Symfony
для пеоепределения шаблонов, живущих внутри пакета:
поместите их в каталоге templates/bundles/TwigBundle/Exception/.

Типичный проект, возвращающий страницы HTML и JSON, может выглядеть так:

Пример шаблона ошибки 404

Чтобы переопределить шаблон ошибки 404 для HTML-страниц, создайте новый шаблон
error404.html.twig, находящийся в templates/bundles/TwigBundle/Exception/:

Если они вам понадобятся, TwigErrorRenderer передаёт некоторую информацию в шаблон
ошибок через переменные status_code и status_text, которые хранят HTTP статус-код
и сообщение соотвественно.

Tip

Вы можете настроить статус-код, реализовав
HttpExceptionInterface
и его обязательный метод getStatusCode(). В обратном случае, status_code
по умолчанию будет500.

Кроме этого у вас есть доступ к Исключениям с помощью exception, который, к примеру,
позволяет вам выводить отслеживание стека, используя {{ exception.traceAsString }}, или
получить доступ к любому другому методу объекта. Однако будьте аккуратны, так как это
с большой вероятностью может обнажить кофиденциальную информацию.

Tip

PHP-ошибки также по умолчанию превращаются в исключения, поэтому вы также можете
получить доступ к деталям этих ошибок, используя exception.

Безопасность и страницы 404

В связи с порядком, в котором загружаются маршрутизация и безопасность, конфиденциальна информация
не будет доступна на ваших страницах 404. Это означает, что будет казаться, что ваш пользователь
не залогинен в систему на странице 404 (это будет работать при тестировании, но не в производстве).

Тестирование страниц ошибок во время разработки

В то время, как вы находитесь в окружении разработки, Symfony отображает
большую страницу исключений вместо вашей новой блестящей страницы ошибок.
Так как вам увидеть, как она выглядит изнутри и отладить её?

К счастью, ExceptionController по умолчанию разрешает вам предпросмотр
вашей страницы ошибки во время разработки.

Чтобы использовать эту функцию, вам загрузить специальные маршруты, предоставленные
TwigBundle (если приложение использует Symfony Flex, то они
загружаются автоматически при установке symfony/framework-bundle):

  • YAML
  • XML
  • PHP

C добавлением этого маршрута, вы можете использовать такие URL для предпросмотра
страницы ошибки для заданного статус-кода в виде HTML или для заданного статус-кода
и формата (вам может понадобиться заменить http://localhost/ на хостинг, используемый
в ваших локальных настройках):

  • http://localhost/_error/{statusCode} для HTML
  • http://localhost/_error/{statusCode}.{format} для любого другого формата

Переопределение вывода ошибок для не-HTML форматов

Чтобы переопределить не-HTML вывод ошибки, необходимо установить компонент Serializer.

Компонент Serializer имеет встроенный нормализатор FlattenException
(ProblemNormalizer) и кодировщики
JSON/XML/CSV/YAML. Когда ваше приложение вызывает исключение, Symfony может вывести его
в один из этих форматов. Если вы хоите изменить содержание вывода, создайте Нормализатор,
который поддерживает ввод FlattenException:

Переопределение ExceptionController по умолчаию

Если вам нужно немного больше гибкости кроме простого переопределения шаблона,
то вы можете изменить контроллер, отображающий странцу ошибки. Например, вам
может быть нужо передать дополнительные переменные в ваш шаблон.

Чтобы сделать это, просто создайте новый контролер где угодно в вашем приложении,
и установите опцию конфигурации framework.error_controller ,
чтобы указать на неё:

  • YAML
  • XML
  • PHP

Класс ExceptionListener,
используемый TwigBundle в качестве слушателя события kernel.exception, создаёт
запрос, который будет развёрнут в вашем контроллере. В дополнение, вашему контроллеру
будут переданы два параметра:

exception
Обработка первоначального экземпляра Throwable.
logger
Экемпляр DebugLoggerInterface,
который может в некоторых случаях быть null.

Tip

Предпросмотр страницы ошибки также работает
с вашими собственными контроллерами, нвстроенными как угодно.

Работа с событием kernel.exception

Когда вызывается исключение, класс HttpKernel
ловит его и развёртывает событие kernel.exception. Это даёт вам возможность
конвертировать исключение в Response несколькими разными способами.

Работа с этим событием на самом деле значительн более мощная, чем объяснялось раньше,
но также требует тщательного понимания внутренних процессов Symfony. Представьте, что
ваш код вызывает специальные исключения с конкретным значением в вашем домене приложения.

Написание вашего собственного слушателя событий для события
kernel.exception позволяет вам ближе рассмотретьисключение и предпринять по отношению
к нему разные действия. Эти действия могут включать в себя запись лога исключения,
перенаправление пользователя на другую страницу или отображение специальных страниц ошибки.

Note

Если ваш слушатель вызывает setResponse() в событии
ExceptionEvent,
распространение будет остановлено и клиенту будет отправлен ответ.

Этот подход позволяет вам создавать централизованную и многослойную обработку
ошибок: вместо того, чтобы ловить (и обрабатывать) одни и те же исключения в
разных контроллерах снова и снова, вы просто можете иметь одного (или нескольких)
слушателей, чтобы разбираться с ними.

Tip

Смотрите код класса ExceptionListener
для реального примера продвинутого слушателя такого типа. Этот слушатель обрабатывает
различные исключения, связанные с безопасностью, которые вызываются в вашем приложении
(как AccessDeniedException) и
предпринимает действия вроде перенаправления пользователей на страницу входа, выполняет
их вход в систему и др.

.. index::
   single: Controller; Customize error pages
   single: Error pages

How to Customize Error Pages

In Symfony applications, all errors are treated as exceptions, no matter if they
are just a 404 Not Found error or a fatal error triggered by throwing some
exception in your code.

If your app has the TwigBundle installed, a special controller handles these
exceptions. This controller displays debug information for errors and allows to
customize error pages, so run this command to make sure the bundle is installed:

$ composer require twig

In the :ref:`development environment <configuration-environments>`,
Symfony catches all the exceptions and displays a special exception page
with lots of debug information to help you discover the root problem:

A typical exception page in the development environment

Since these pages contain a lot of sensitive internal information, Symfony won’t
display them in the production environment. Instead, it’ll show a simple and
generic error page:

A typical error page in the production environment

Error pages for the production environment can be customized in different ways
depending on your needs:

  1. If you just want to change the contents and styles of the error pages to match
    the rest of your application, :ref:`override the default error templates <use-default-exception-controller>`;
  2. If you also want to tweak the logic used by Symfony to generate error pages,
    :ref:`override the default exception controller <custom-exception-controller>`;
  3. If you need total control of exception handling to execute your own logic
    :ref:`use the kernel.exception event <use-kernel-exception-event>`.

Overriding the Default Error Templates

When the error page loads, an internal :class:`Symfony\Bundle\TwigBundle\Controller\ExceptionController`
is used to render a Twig template to show the user.

This controller uses the HTTP status code, the request format and the following
logic to determine the template filename:

  1. Look for a template for the given format and status code (like error404.json.twig
    or error500.html.twig);
  2. If the previous template doesn’t exist, discard the status code and look for
    a generic template for the given format (like error.json.twig or
    error.xml.twig);
  3. If none of the previous templates exist, fall back to the generic HTML template
    (error.html.twig).

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

A typical project that returns HTML and JSON pages might look like this:

templates/
└─ bundles/
   └─ TwigBundle/
      └─ Exception/
         ├─ error404.html.twig
         ├─ error403.html.twig
         ├─ error.html.twig      # All other HTML errors (including 500)
         ├─ error404.json.twig
         ├─ error403.json.twig
         └─ error.json.twig      # All other JSON errors (including 500)

Example 404 Error Template

To override the 404 error template for HTML pages, create a new
error404.html.twig template located at templates/bundles/TwigBundle/Exception/:

{# templates/bundles/TwigBundle/Exception/error404.html.twig #}
{% extends 'base.html.twig' %}

{% block body %}
    <h1>Page not found</h1>

    <p>
        The requested page couldn't be located. Checkout for any URL
        misspelling or <a href="{{ path('homepage') }}">return to the homepage</a>.
    </p>
{% endblock %}

In case you need them, the ExceptionController passes some information to
the error template via the status_code and status_text variables that
store the HTTP status code and message respectively.

Tip

You can customize the status code by implementing
:class:`Symfony\Component\HttpKernel\Exception\HttpExceptionInterface`
and its required getStatusCode() method. Otherwise, the status_code
will default to 500.

Note

The exception pages shown in the development environment can be customized
in the same way as error pages. Create a new exception.html.twig template
for the standard HTML exception page or exception.json.twig for the JSON
exception page.

Security & 404 Pages

Due to the order of how routing and security are loaded, security information will
not be available on your 404 pages. This means that it will appear as if your
user is logged out on the 404 page (it will work while testing, but not on production).

Testing Error Pages during Development

While you’re in the development environment, Symfony shows the big exception
page instead of your shiny new customized error page. So, how can you see
what it looks like and debug it?

Fortunately, the default ExceptionController allows you to preview your
error pages during development.

To use this feature, you need to load some special routes provided by TwigBundle
(if the application uses :ref:`Symfony Flex <symfony-flex>` they are loaded
automatically when installing Twig support):

.. configuration-block::

    .. code-block:: yaml

        # config/routes/dev/twig.yaml
        _errors:
            resource: '@TwigBundle/Resources/config/routing/errors.xml'
            prefix:   /_error

    .. code-block:: xml

        <!-- config/routes/dev/twig.xml -->
        <?xml version="1.0" encoding="UTF-8" ?>
        <routes xmlns="http://symfony.com/schema/routing"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://symfony.com/schema/routing
                https://symfony.com/schema/routing/routing-1.0.xsd">

            <import resource="@TwigBundle/Resources/config/routing/errors.xml" prefix="/_error"/>
        </routes>

    .. code-block:: php

        // config/routes/dev/twig.php
        use SymfonyComponentRoutingLoaderConfiguratorRoutingConfigurator;

        return function (RoutingConfigurator $routes) {
            $routes->import('@TwigBundle/Resources/config/routing/errors.xml')
                ->prefix('/_error')
            ;
        };

With this route added, you can use URLs like these to preview the error page
for a given status code as HTML or for a given status code and format.

http://localhost/index.php/_error/{statusCode}
http://localhost/index.php/_error/{statusCode}.{format}

Overriding 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.

To do this, create a new controller anywhere in your application and set
the :ref:`twig.exception_controller <config-twig-exception-controller>`
configuration option to point to it:

.. configuration-block::

    .. code-block:: yaml

        # config/packages/twig.yaml
        twig:
            exception_controller: AppControllerExceptionController::showAction

    .. code-block:: xml

        <!-- config/packages/twig.xml -->
        <?xml version="1.0" encoding="UTF-8" ?>
        <container xmlns="http://symfony.com/schema/dic/services"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:twig="http://symfony.com/schema/dic/twig"
            xsi:schemaLocation="http://symfony.com/schema/dic/services
                https://symfony.com/schema/dic/services/services-1.0.xsd
                http://symfony.com/schema/dic/twig
                https://symfony.com/schema/dic/twig/twig-1.0.xsd">

            <twig:config>
                <twig:exception-controller>AppControllerExceptionController::showAction</twig:exception-controller>
            </twig:config>

        </container>

    .. code-block:: php

        // config/packages/twig.php
        $container->loadFromExtension('twig', [
            'exception_controller' => 'AppControllerExceptionController::showAction',
            // ...
        ]);

The :class:`Symfony\Component\HttpKernel\EventListener\ExceptionListener`
class used by the TwigBundle as a listener of the kernel.exception event creates
the request that will be dispatched to your controller. In addition, your controller
will be passed two parameters:

exception
A :class:`\Symfony\Component\Debug\Exception\FlattenException`
instance created from the exception being handled.
logger
A :class:`\Symfony\Component\HttpKernel\Log\DebugLoggerInterface`
instance which may be null in some circumstances.

Instead of creating a new exception controller from scratch you can also extend
the default :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.

Note

In case of extending the
:class:`Symfony\Bundle\TwigBundle\Controller\ExceptionController` you
may configure a service to pass the Twig environment and the debug flag
to the constructor.

.. configuration-block::

    .. code-block:: yaml

        # config/services.yaml
        services:
            _defaults:
                # ... be sure autowiring is enabled
                autowire: true
            # ...

            AppControllerCustomExceptionController:
                public: true
                arguments:
                    $debug: '%kernel.debug%'

    .. code-block:: xml

        <!-- config/services.xml -->
        <?xml version="1.0" encoding="UTF-8" ?>
        <container xmlns="http://symfony.com/schema/dic/services"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://symfony.com/schema/dic/services
                https://symfony.com/schema/dic/services/services-1.0.xsd">

            <services>
                <!-- ... be sure autowiring is enabled -->
                <defaults autowire="true"/>
                <!-- ... -->

                <service id="AppControllerCustomExceptionController" public="true">
                    <argument key="$debug">%kernel.debug%</argument>
                </service>
            </services>

        </container>

    .. code-block:: php

        // config/services.php
        use AppControllerCustomExceptionController;

        $container->autowire(CustomExceptionController::class)
            ->setArgument('$debug', '%kernel.debug%');

Tip

The :ref:`error page preview <testing-error-pages>` also works for
your own controllers set up this way.

Working with the kernel.exception Event

When an exception is thrown, the :class:`Symfony\Component\HttpKernel\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.

Working with this event is actually much more powerful than what has been explained
before, but also requires a thorough understanding of Symfony internals. Suppose
that your code throws specialized exceptions with a particular meaning to your
application domain.

:doc:`Writing your own event listener </event_dispatcher>`
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\ExceptionEvent`,
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
time and again, you can have just one (or several) listeners deal with them.

Tip

See :class:`Symfony\Component\Security\Http\Firewall\ExceptionListener`
class code for a real example of an advanced listener of this type. This
listener 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.

Customizing Error Pages and How Errors are Handled¶

Sometimes things fall apart. And when they do, we show our users an error
page. Hopefully, a hilarious error page.

Right now, our 404 page isn’t very hilarous, except for the little Pacman
ghost that’s screaming “Exception detected”. He’s adorable.

We see this big descriptive error page because we’re in the dev environment,
and Symfony wants to help us fix our mistake. In real life, also known as
the prod environment, it’s different.

The Real Life: prod Environment¶

To see our app in its “real life” form, put an app.php after localhost:

We talked about environments and this app.php stuff in episode 1.
If you don’t remember it, go back and check it out!

The page might work or it might be broken. That’s because we always need
to clear our Symfony cache when going into the prod environment:

php app/console cache:clear --env=prod

Ok, now the site works. Invent a URL to see the 404 page. Ah gross! This
error page isn’t hilarous at all! So where is the content for this page actually
coming from and how can we make a better experience for our users?

Overriding the Error Template Content¶

To find out, let’s just search the project! In PHPStorm, I can navigate
to vendor/symfony/symfony, right click, then select “Find in Path”. Let’s
look for the “An Error Occurred” text.

Ah hah! It points us straight to a file in the core Twig bundle called error.html.twig.
Let’s open that up!

Tip

The location of the file is:

vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Resources/views/Exception/error.html.twig

Cool, so how can we replace this with a template that has unicorns, or pirates
or anything better than this?

There’s actually a really neat trick that let’s you override any template
from any bundle. All we need to do is create a template with the same
name as this in just the right location.

This template lives in TwigBundle and in an Exception directory.
Create an app/Resources/TwigBundle/views/Exception/error.html.twig file.
Notice how similar the paths are — it’s the magic way to override any
template from any bundle.

Tip

app/Resources/AnyBundle/views/SomeDir/myTemplate.html.twig
will always override
@AnyBundle/Resources/views/SomeDir/myTemplate.html.twig

Now just extend the base template and put something awesome inside. I’m
going to abuse my login.css file to get this to look ok. I know, I really
need to clean up my CSS:

{# app/Resources/TwigBundle/views/Exception/error.html.twig #}
{% extends '::base.html.twig' %}

{% block stylesheets %}
    {{ parent() }}
    <link rel="stylesheet" href="{{ asset('bundles/user/css/login.css') }}" />
{% endblock %}

{% block body %}
    <section class="login">
        <article>
            <h1>Ah crap!</h1>

            <div>These are not the droids you're looking for...</div>
        </article>
    </section>
{% endblock %}

Refresh! Hey, don’t act so surprised to see the same ugly template. We’re in
the prod environment, we need to clear our cache after every change:

php app/console cache:clear --env=prod

Refresh again. It’s beautiful. The pain with customizing error templates
is that you need to be in the prod environment to see them. And that
means you need to remember to clear cache after every change.

Customizing Error Pages by Type (Status Code)¶

But we have a problem: this template is used for all errors: 404 errors,
500 errors and even the dreaded 418 error!

I think we should at least have one template for 404 errors and another for
everything else. Copy the existing template and paste it into a new file
called error404.html.twig. That’s the trick, and this works for customizing
the error page of any HTTP status code.

We should keep the generic error template, but let’s give it a different
message:

{# app/Resources/TwigBundle/views/Exception/error.html.twig #}

{# ... #}
<h1>Ah crap!</h1>

<div>The servers are on fire! Grab a bucket! Send halp!</div>

To see the 404 template, clear your cache and refresh again on an imaginary
URL. To see the other template, temporarily throw an exception in EventController::indexAction
to cause a 500 error:

// src/Yoda/EventBundle/Controller/EventController.php
// ...

public function indexAction()
{
    throw new Exception('Ahhhhahahhhah');
    // ...
}

Head to the homepage — but with the app.php still in the URL. You should
see that the servers are in fact on fire, which I guess is cool. Remove this
exception before moving on.

Going Deeper with Exception Handling¶

Behind the scenes, Symfony dispatches an event whenever an exception happens.
We haven’t talked about events yet, but this basically means that if you
want, you can be nofitied whenever an exception is thrown anywhere in your
code. Why would you do this? You might want to do some extra logging or even
completely replace which template is rendered when an error happens.

We won’t cover event listeners in this screencast, but there’s a cookbook
called How to Create an Event Listener that covers it.

Normally, when there’s an exception, Symfony calls an internal controller
that renders the error template. This class lives in TwigBundle and is called
ExceptionController. Let’s open it up!

The class lives at:
vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php

The guts of this class aren’t too important, but you can see it trying
to figure out which template to render in findTemplate. You can even
see it looking for the status-code version of the template, like error404.html.twig:

// vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php
// ...

$template = new TemplateReference('TwigBundle', 'Exception', $name.$code, $format, 'twig');
if ($this->templateExists($template)) {
    return $template;
}

I’m making you stare at this class because, if you want, you can actually
override this entire controller. If you do that, then your controller function
will be called whenever there’s an error and you can render whatever page
you want. That process is a bit more involved, but use it if you need to go
even further.

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=5.3.3",
        "symfony/symfony": "~2.4", // v2.4.2
        "doctrine/orm": "~2.2,>=2.2.3", // v2.4.2
        "doctrine/doctrine-bundle": "~1.2", // v1.2.0
        "twig/extensions": "~1.0", // v1.0.1
        "symfony/assetic-bundle": "~2.3", // v2.3.0
        "symfony/swiftmailer-bundle": "~2.3", // v2.3.5
        "symfony/monolog-bundle": "~2.4", // v2.5.0
        "sensio/distribution-bundle": "~2.3", // v2.3.4
        "sensio/framework-extra-bundle": "~3.0", // v3.0.0
        "sensio/generator-bundle": "~2.3", // v2.3.4
        "incenteev/composer-parameter-handler": "~2.0", // v2.1.0
        "doctrine/doctrine-fixtures-bundle": "~2.2.0", // v2.2.0
        "ircmaxell/password-compat": "~1.0.3", // 1.0.3
        "phpunit/phpunit": "~4.1", // 4.1.0
        "stof/doctrine-extensions-bundle": "~1.1.0" // v1.1.0
    }
}

Содержание

  1. How to Customize Error Pages
  2. Overriding the Default Error Templates
  3. Example 404 Error Template
  4. Security & 404 Pages
  5. Testing Error Pages during Development
  6. Overriding Error output for non-HTML formats
  7. Overriding the Default ErrorController
  8. Working with the kernel.exception Event
  9. How the HTML Error Page is Rendered
  10. Keep on Learning!
  11. Error Renderer Decoration
  12. HtmlErrorRenderer: Default Exception & Error Templates
  13. Name already in use
  14. symfony-docs-ru / controller / error_pages.rst

How to Customize Error Pages

In Symfony applications, all errors are treated as exceptions, no matter if they are a 404 Not Found error or a fatal error triggered by throwing some exception in your code.

In the development environment, Symfony catches all the exceptions and displays a special exception page with lots of debug information to help you discover the root problem:

Since these pages contain a lot of sensitive internal information, Symfony won’t display them in the production environment. Instead, it’ll show a minimal and generic error page:

Error pages for the production environment can be customized in different ways depending on your needs:

  1. If you only want to change the contents and styles of the error pages to match the rest of your application, override the default error templates;
  2. If you want to change the contents of non-HTML error output, create a new normalizer;
  3. If you also want to tweak the logic used by Symfony to generate error pages, override the default error controller;
  4. If you need total control of exception handling to run your own logic use the kernel.exception event.

Overriding the Default Error Templates

You can use the built-in Twig error renderer to override the default error templates. Both the TwigBundle and TwigBridge need to be installed for this. Run this command to ensure both are installed:

When the error page loads, TwigErrorRenderer is used to render a Twig template to show the user.

This renderer uses the HTTP status code and the following logic to determine the template filename:

  1. Look for a template for the given status code (like error500.html.twig );
  2. If the previous template doesn’t exist, discard the status code and look for a generic error template ( error.html.twig ).

To override these templates, rely on the standard Symfony method for overriding templates that live inside a bundle and put them in the templates/bundles/TwigBundle/Exception/ directory.

A typical project that returns HTML pages might look like this:

Example 404 Error Template

To override the 404 error template for HTML pages, create a new error404.html.twig template located at templates/bundles/TwigBundle/Exception/ :

In case you need them, the TwigErrorRenderer passes some information to the error template via the status_code and status_text variables that store the HTTP status code and message respectively.

You can customize the status code of an exception by implementing HttpExceptionInterface and its required getStatusCode() method. Otherwise, the status_code will default to 500 .

Additionally you have access to the Exception with exception , which for example allows you to output the stack trace using << exception.traceAsString >> or access any other method on the object. You should be careful with this though, as this is very likely to expose sensitive data.

PHP errors are turned into exceptions as well by default, so you can also access these error details using exception .

Security & 404 Pages

Due to the order of how routing and security are loaded, security information will not be available on your 404 pages. This means that it will appear as if your user is logged out on the 404 page (it will work while testing, but not on production).

Testing Error Pages during Development

While you’re in the development environment, Symfony shows the big exception page instead of your shiny new customized error page. So, how can you see what it looks like and debug it?

Fortunately, the default ErrorController allows you to preview your error pages during development.

To use this feature, you need to load some special routes provided by FrameworkBundle (if the application uses Symfony Flex they are loaded automatically when installing symfony/framework-bundle ):

With this route added, you can use URLs like these to preview the error page for a given status code as HTML or for a given status code and format (you might need to replace http://localhost/ by the host used in your local setup):

  • http://localhost/_error/ for HTML
  • http://localhost/_error/. for any other format

Overriding Error output for non-HTML formats

To override non-HTML error output, the Serializer component needs to be installed.

The Serializer component has a built-in FlattenException normalizer (ProblemNormalizer) and JSON/XML/CSV/YAML encoders. When your application throws an exception, Symfony can output it in one of those formats. If you want to change the output contents, create a new Normalizer that supports the FlattenException input:

Overriding the Default ErrorController

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.

To do this, create a new controller anywhere in your application and set the framework.error_controller configuration option to point to it:

The ErrorListener class used by the FrameworkBundle as a listener of the kernel.exception event creates the request that will be dispatched to your controller. In addition, your controller will be passed two parameters:

exception The original Throwable instance being handled. logger A DebugLoggerInterface instance which may be null in some circumstances.

The error page preview also works for your own controllers set up this way.

Working with the kernel.exception Event

When an exception is thrown, the 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.

Working with this event is actually much more powerful than what has been explained before, but also requires a thorough understanding of Symfony internals. Suppose that your code throws specialized exceptions with a particular meaning to your application domain.

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.

If your listener calls setThrowable() on the ExceptionEvent 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 time and again, you can have just one (or several) listeners deal with them.

See ExceptionListener class code for a real example of an advanced listener of this type. This listener handles various security-related exceptions that are thrown in your application (like AccessDeniedException) and takes measures like redirecting the user to the login page, logging them out and other things.

Источник

How the HTML Error Page is Rendered

Keep on Learning!

If you liked what you’ve learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

With a Subscription, click any sentence in the script to jump to that part of the video!

When you use a browser, the format will be html . That’s also the default format if no request format was set and if the request doesn’t contain an Accept header. In the case of html , the serializer will fail by throwing a NotEncodableValueException . When that happens, this offloads the work to another error render: $this->fallbackErrorRenderer .

If you dumped this object, you’d find out that it’s an instance of TwigErrorRenderer . Ok! Let’s open that up: Shift + Shift TwigErrorRender.php .

It. interesting! It immediately calls another fallbackErrorRenderer . This one is an instance of HtmlErrorRender . Open it up: HtmlErrorRenderer.php .

Error Renderer Decoration

Then. stop. Let me explain why and how we have three different error renderer classes. This HtmlErrorRenderer is the, sort of, «core» error renderer and it always exists. But if you have Twig installed, the TwigErrorRenderer suddenly «takes over» the error rendering process. It does that via service decoration: TwigErrorRenderer decorates HtmlErrorRenderer .

And then. if you have the serializer component installed, suddenly there is a third error renderer added to the system: SerializerErrorRenderer , which decorates TwigErrorRenderer .

This is a slight over-simplification, but there is basically only ever one official «error renderer» service registered in the container. It’s id is error_renderer . But through service decoration, multiple error renderers are ultimately used.

HtmlErrorRenderer: Default Exception & Error Templates

Let’s look at the flow. TwigErrorRender calls render() on HtmlErrorRenderer . Remember: the render() method on all of these classes has the same job: to return a FlattenException that contains the status code, headers and the «body» that will be used for the Response.

So, it’s no surprise that this once again starts by creating a FlattenException object. To get the «body» of the response, it calls $this->renderException() . Jump to that.

This is what builds the error or exception page. The $debugTemplate argument defaults to views/exception_full.html.php . Yea, this method render PHP templates! This template will be used in debug mode. If we’re not in debug mode, then it «includes» — basically, renders — error.html.php . So exception_full.html.php in debug mode, error.html.php on production. The include() function is as simple as it gets.

Let’s go see the debug template. Using the directory tree on top. click the error-handler/ directory, then navigate to open Resources/views/exception_full.html.php

This is what we’re seeing in our browser right now. To prove it, in the middle, let’s add:

Источник

Name already in use

symfony-docs-ru / controller / error_pages.rst

  • Go to file T
  • Go to line L
  • Copy path
  • Copy permalink

Copy raw contents

Copy raw contents

How to Customize Error Pages

In Symfony applications, all errors are treated as exceptions, no matter if they are just a 404 Not Found error or a fatal error triggered by throwing some exception in your code.

If your app has the TwigBundle installed, a special controller handles these exceptions. This controller displays debug information for errors and allows to customize error pages, so run this command to make sure the bundle is installed:

In the :ref:`development environment ` , Symfony catches all the exceptions and displays a special exception page with lots of debug information to help you discover the root problem:

Since these pages contain a lot of sensitive internal information, Symfony won’t display them in the production environment. Instead, it’ll show a simple and generic error page:

Error pages for the production environment can be customized in different ways depending on your needs:

  1. If you just want to change the contents and styles of the error pages to match the rest of your application, :ref:`override the default error templates ` ;
  2. If you also want to tweak the logic used by Symfony to generate error pages, :ref:`override the default exception controller ` ;
  3. If you need total control of exception handling to execute your own logic :ref:`use the kernel.exception event ` .

Overriding the Default Error Templates

When the error page loads, an internal :class:`Symfony\Bundle\TwigBundle\Controller\ExceptionController` is used to render a Twig template to show the user.

This controller uses the HTTP status code, the request format and the following logic to determine the template filename:

  1. Look for a template for the given format and status code (like error404.json.twig or error500.html.twig );
  2. If the previous template doesn’t exist, discard the status code and look for a generic template for the given format (like error.json.twig or error.xml.twig );
  3. If none of the previous templates exist, fall back to the generic HTML template ( error.html.twig ).

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

A typical project that returns HTML and JSON pages might look like this:

Example 404 Error Template

To override the 404 error template for HTML pages, create a new error404.html.twig template located at templates/bundles/TwigBundle/Exception/ :

In case you need them, the ExceptionController passes some information to the error template via the status_code and status_text variables that store the HTTP status code and message respectively.

You can customize the status code by implementing :class:`Symfony\Component\HttpKernel\Exception\HttpExceptionInterface` and its required getStatusCode() method. Otherwise, the status_code will default to 500 .

The exception pages shown in the development environment can be customized in the same way as error pages. Create a new exception.html.twig template for the standard HTML exception page or exception.json.twig for the JSON exception page.

Security & 404 Pages

Due to the order of how routing and security are loaded, security information will not be available on your 404 pages. This means that it will appear as if your user is logged out on the 404 page (it will work while testing, but not on production).

Testing Error Pages during Development

While you’re in the development environment, Symfony shows the big exception page instead of your shiny new customized error page. So, how can you see what it looks like and debug it?

Fortunately, the default ExceptionController allows you to preview your error pages during development.

To use this feature, you need to load some special routes provided by TwigBundle (if the application uses :ref:`Symfony Flex ` they are loaded automatically when installing Twig support):

With this route added, you can use URLs like these to preview the error page for a given status code as HTML or for a given status code and format.

Overriding 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.

To do this, create a new controller anywhere in your application and set the :ref:`twig.exception_controller ` configuration option to point to it:

The :class:`Symfony\Component\HttpKernel\EventListener\ExceptionListener` class used by the TwigBundle as a listener of the kernel.exception event creates the request that will be dispatched to your controller. In addition, your controller will be passed two parameters:

Instead of creating a new exception controller from scratch you can also extend the default :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.

In case of extending the :class:`Symfony\Bundle\TwigBundle\Controller\ExceptionController` you may configure a service to pass the Twig environment and the debug flag to the constructor.

The :ref:`error page preview ` also works for your own controllers set up this way.

Working with the kernel.exception Event

When an exception is thrown, the :class:`Symfony\Component\HttpKernel\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.

Working with this event is actually much more powerful than what has been explained before, but also requires a thorough understanding of Symfony internals. Suppose that your code throws specialized exceptions with a particular meaning to your application domain.

: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.

If your listener calls setResponse() on the :class:`Symfony\Component\HttpKernel\Event\ExceptionEvent` , 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 time and again, you can have just one (or several) listeners deal with them.

See :class:`Symfony\Component\Security\Http\Firewall\ExceptionListener` class code for a real example of an advanced listener of this type. This listener 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.

Источник

В приложениях Symfony все ошибки рассматриваются как исключения Exception, независимо от того, являются ли они просто ошибкой 404 Not Found или фатальной ошибкой, вызванной возникновением некоторого исключения в вашем коде.

В среде разработки Symfony перехватывает все исключения и отображает специальную страницу исключений со множеством отладочной информации, которая поможет вам обнаружить корневую проблему:

Поскольку такие страницы содержат много конфиденциальной внутренней информации, Symfony не будет отображать их в production среде. Вместо этого он покажет простую и общую страницу ошибок:

Страницы ошибок для production среды могут быть настроены по-разному в зависимости от ваших потребностей:

  1. Если вы просто хотите изменить содержимое и стили страниц ошибок, чтобы они соответствовали остальной части вашего приложения, переопределите шаблоны ошибок по умолчанию;
  2. Если вы хотите изменить содержимое вывода ошибок, отличных от HTML, создайте новый нормализатор;
  3. Если вы также хотите настроить логику, используемую Symfony для генерации страниц ошибок, переопределите контроллер ошибок по умолчанию;
  4. Если вам нужен полный контроль над обработкой исключений для выполнения вашей собственной логики, используйте событие kernel.exception.

Как переопределить шаблон страницы ошибок по умолчанию?

Вы можете использовать встроенный обработчик ошибок Twig, чтобы переопределить шаблоны ошибок по умолчанию. Для этого должны быть установлены как TwigBundle, так и TwigBridge. Запустите эту команду, чтобы убедиться, что оба установлены:

Когда страница ошибки загружается, TwigErrorRenderer используется для визуализации шаблона Twig для отображения пользователю.

Этот рендерер использует код состояния HTTP и следующую логику для определения имени файла шаблона:

  1. Находится шаблон для данного кода состояния (например, error500.html.twig);
  2. Если предыдущий шаблон не существует, то игнорируется код состояния и находится общий шаблон ошибки (error.html.twig).

Чтобы переопределить эти шаблоны, используйте стандартный метод Symfony для переопределения шаблонов, которые находятся внутри пакета, и поместите их в каталог templates/bundles/TwigBundle/Exception/.

Типичный проект, который возвращает HTML-страницы, может выглядеть так:

templates/
└─ bundles/
   └─ TwigBundle/
      └─ Exception/
         ├─ error404.html.twig
         ├─ error403.html.twig
         └─ error.html.twig      # All other HTML errors (including 500)

Пример 404 Шаблона ошибки

Чтобы переопределить шаблон ошибки 404 для страниц HTML, создайте новый шаблон error404.html.twig, расположенный в шаблонах /bundles/TwigBundle/Exception /:

{# templates/bundles/TwigBundle/Exception/error404.html.twig #}
{% extends 'base.html.twig' %}

{% block body %}
    <h1>Page not found</h1>

    <p>
        The requested page couldn't be located. Checkout for any URL
        misspelling or <a href="{{ path('homepage') }}">return to the homepage</a>.
    </p>
{% endblock %}

Если вам потребуется, TwigErrorRenderer передает некоторую информацию в шаблон ошибки через переменные status_code и status_text, которые хранят код состояния HTTP и сообщение соответственно.

Вы можете настроить код состояния исключения, реализовав HttpExceptionInterface и его обязательный метод getStatusCode(). В противном случае код_состояния по умолчанию будет равен 500.

Тестирование страниц ошибок в режиме develop.

Пока вы находитесь в среде develop, Symfony показывает большую страницу исключений вместо вашей новой блестящей настраиваемой страницы ошибок. Итак, как вы можете увидеть, как это выглядит и отладить его?

К счастью, ErrorController по умолчанию позволяет вам просматривать страницы ошибок во время разработки.

Чтобы использовать эту функцию, вам нужно загрузить некоторые специальные маршруты, предоставляемые FrameworkBundle (если приложение использует Symfony Flex, они загружаются автоматически при установке symfony/framework-bundle):

# config/routes/dev/framework.yaml
_errors:
    resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
    prefix:   /_error

После добавления этого маршрута вы можете использовать подобные URL-адреса для предварительного просмотра страницы ошибки для заданного кода состояния в виде HTML или для заданного кода состояния и формата.

http://localhost/index.php/_error/{statusCode}
http://localhost/index.php/_error/{statusCode}.{format}

Переопределение вывода ошибок для не-HTML форматов.

Чтобы переопределить вывод ошибок, в формате отличном от HTML, необходимо установить компонент Serializer.

 composer require serializer

Компонент Serializer имеет встроенный нормализатор FlattenException (ProblemNormalizer) и енкодеры JSON / XML / CSV / YAML. Когда ваше приложение выдает исключение, Symfony может вывести его в одном из этих форматов. Если вы хотите изменить содержимое вывода, создайте новый нормализатор, который поддерживает вход FlattenException:

# src/App/Serializer/MyCustomProblemNormalizer.php
namespace AppSerializer;

use SymfonyComponentSerializerNormalizerNormalizerInterface;

class MyCustomProblemNormalizer implements NormalizerInterface
{
    public function normalize($exception, string $format = null, array $context = [])
    {
        return [
            'content' => 'This is my custom problem normalizer.',
            'exception'=> [
                'message' => $exception->getMessage(),
                'code' => $exception->getStatusCode(),
            ],
        ];
    }

    public function supportsNormalization($data, string $format = null)
    {
        return $data instanceof FlattenException;
    }
}

Переопределение стандартного ErrorController.

Если вам нужно немного больше гибкости, чем просто переопределение шаблона, вы можете изменить контроллер, отображающий страницу с ошибкой. Например, вам может потребоваться передать некоторые дополнительные переменные в ваш шаблон.

Для этого создайте новый контроллер в любом месте вашего приложения и установите параметр конфигурации framework.error_controller, чтобы он указывал на него:

# config/packages/framework.yaml
framework:
    error_controller: AppControllerErrorController::showAction

Класс ErrorListener, используемый FrameworkBundle в качестве прослушивателя события kernel.exception, создает запрос, который будет отправлен вашему контроллеру. Кроме того, вашему контроллеру будут переданы два параметра:

  • exception — Экземпляр FlattenException, созданный из обрабатываемого исключения.
  • logger — Экземпляр DebugLoggerInterface, который может быть null в некоторых случаях.

Вместо создания нового контроллера исключений с нуля вы также можете расширить ExceptionController по умолчанию. В этом случае вы можете переопределить один или оба метода showAction() и findTemplate(). Последний находит шаблон для использования.

В случае расширения ExceptionController вы можете настроить сервис для передачи окружения Twig и флага отладки в конструктор.

# config/services.yaml
services:
    _defaults:
        # ... be sure autowiring is enabled
        autowire: true
    # ...

    AppControllerCustomExceptionController:
        public: true
        arguments:
            $debug: '%kernel.debug%'

Работа с событием kernel.exception

Когда бросается exception, класс HttpKernel перехватывает его и отправляет событие kernel.exception. Это дает вам возможность преобразовать исключение в ответ несколькими различными способами.

Работа с этим событием на самом деле намного эффективнее, чем было объяснено ранее, но также требует глубокого понимания внутренних возможностей Symfony. Предположим, что ваш код выдает специализированные исключения с особым значением в область вашего приложения.

Написание собственного слушателя событий для события kernel.exception позволяет вам ближе рассмотреть исключение и предпринять различные действия в зависимости от него. Эти действия могут включать логирование исключения, редирект пользователя на другую страницу или отображение специализированных страниц с ошибками.

Если ваш слушатель вызывает setResponse() для ExceptionEvent, событие, дальнейшая обработка другими слушателями будет остановлено, и ответ будет отправлен клиенту.

Этот подход позволяет вам создавать централизованную и многоуровневую обработку ошибок: вместо того, чтобы снова и снова перехватывать (и обрабатывать) одни и те же исключения в различных контроллерах, вы можете иметь дело только с одним (или несколькими) слушателями.

As I make my way through some tutorials on SymfonyCasts and begin a re-write of my SyntaxSeed website from CodeIgniter to Symfony… I occasionally encounter something that took a bit more struggle than a simple web search. This is one of those tasks.

Symfony gives you some generic built in error pages, for example when you get a 404 missing resource error or a 500 error. When working in your dev environment you don’t see these, you instead get the nice Whoops error pages with extra details. Customizing the error pages requires a few steps.

First off, I assume you are using Symfony version 5.1 or later and are using the Twig templating engine.

Begin by ensuring you have both Twig and the Twig-Pack installed in your project with Composer:

composer require twig
composer require symfony/twig-pack

Bonus Side Note…. while you’re at it you might want some nice extras in Twig including filters like truncate() or wordwrap. You can install these with:

composer require twig/string-extra
composer require twig/extra-bundle

And use them like so:

{{ summary|u.truncate(100, '...') }}

Anyway, where were we… oh yes… customising the error pages. Once you have the twig-pack installed you need to create a set of new files:

/templates/bundles/TwigBundle/Exception/
   - error404.html.twig
   - error500.html.twig
   - error.html.twig 

Create one for each error type you wish to customise and create error.html.twig as a fallback for all other error types.

Previewing Your Custom Symfony Error Pages

Ok so you’ve made a nice error page… how do you check it out? As you work on your project you’re probably in the dev environment (configured in your .env file). This means when you get errors you will probably see the helpful Symfony error page with the ghost in the upper right.

Your first option is to switch your environment in the .env file from dev to prod. Then make sure you clear your template cache:

php bin/console cache:clear --env=prod

Now if you visit a non-existing route, you should see your 404 page.

How do you preview these pages while still being in the dev environment? Symfony has a special route to do so:

https://127.0.0.1:8000/index.php/_error/404

Replace the code number on the end with the type of error you want to preview. Note that your local site might be using localhost instead of 127.0.0.1:8000. I believe this only works in the dev environment.

It’s Still Not Working!?

Ensure that you have cleared your cache a few times in the correct environment and that the path and filenames for your custom error pages are correct. Also have a look in your composer.json file and ensure you have the right composer packages installed. For me, I have (this is for a Symfony 5.2 project):

"symfony/twig-bundle": "5.2.*",
"twig/extra-bundle": "^3.3",
"twig/twig": "^2.12|^3.0"

To be honest, this process was a bit finicky for me. I had to re-install the twig-pack a couple times before it would work. I did not have to add any special config values, routes or service hooks or anything to get this to work. I re-installed the pack, removed any Twig code from my templates, clear the cache and it worked. I then added Twig code back into the template and it continued to work.

I hope this was helpful – thanks for reading!

When any exception is thrown in Symfony2, 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.

Error pages can be customized in two different ways, depending on how much
control you need:

  1. Customize the error templates of the different error pages (explained below);
  2. Replace the default exception controller TwigBundle::Exception:show
    with your own controller and handle it however you want (see
    exception_controller in the Twig reference);

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 kernel.exception Event.

All of the error templates live inside TwigBundle. To override the
templates, we simply rely on the standard method for overriding templates that
live inside a bundle. For more information, see
Overriding Bundle Templates.

For example, to override the default error template that’s shown to the
end-user, create a new template located at
app/Resources/TwigBundle/views/Exception/error.html.twig:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>An Error Occurred: {{ status_text }}</title>
</head>
<body>
    <h1>Oops! An Error Occurred</h1>
    <h2>The server returned a "{{ status_code }} {{ status_text }}".</h2>
</body>
</html>

Tip

If you’re not familiar with Twig, don’t worry. Twig is a simple, powerful
and optional templating engine that integrates with Symfony2. For more
information about Twig see Creating and using Templates.

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.

Customizing the 404 Page and other Error Pages¶

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.

Symfony uses the following algorithm to determine which template to use:

  • First, it looks for a template for the given format and status code (like
    error404.json.twig);
  • If it does not exist, it looks for a template for the given format (like
    error.json.twig);
  • If it does not exist, it falls back to the HTML template (like
    error.html.twig).

Tip

To see the full list of default error templates, see the
Resources/views/Exception directory of the TwigBundle. In a
standard Symfony2 installation, the TwigBundle can be found at
vendor/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.

Note

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.

Понравилась статья? Поделить с друзьями:
  • Symfony 500 internal server error
  • Symfony 404 error
  • Symbols error huawei что это
  • Symbol lookup error undefined symbol linux
  • Symbol error rate это