Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 5 additions & 56 deletions components/debug.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Installation

.. code-block:: terminal

$ composer require symfony/debug
$ composer require --dev symfony/debug

.. include:: /components/require_autoload.rst.inc

Expand All @@ -26,64 +26,13 @@ Enable all of them by calling this method::

Debug::enable();

The :method:`Symfony\\Component\\Debug\\Debug::enable` method registers an
error handler, an exception handler and
:ref:`a special class loader <component-debug-class-loader>`.

Read the following sections for more information about the different available
tools.

.. caution::

You should never enable the debug tools, except for the error handler, in a
production environment as they might disclose sensitive information to the user.

Enabling the Error Handler
--------------------------

The :class:`Symfony\\Component\\Debug\\ErrorHandler` class catches PHP errors
and converts them to exceptions (of class :phpclass:`ErrorException` or
:class:`Symfony\\Component\\Debug\\Exception\\FatalErrorException` for PHP
fatal errors)::

use Symfony\Component\Debug\ErrorHandler;

ErrorHandler::register();

This error handler is enabled by default in the production environment when the
application uses the FrameworkBundle because it generates better error logs.

Enabling the Exception Handler
------------------------------

The :class:`Symfony\\Component\\Debug\\ExceptionHandler` class catches
uncaught PHP exceptions and converts them to a nice PHP response. It is useful
in debug mode to replace the default PHP/XDebug output with something prettier
and more useful::

use Symfony\Component\Debug\ExceptionHandler;

ExceptionHandler::register();

.. note::

If the :doc:`HttpFoundation component </components/http_foundation>` is
available, the handler uses a Symfony Response object; if not, it falls
back to a regular PHP response.

.. _component-debug-class-loader:

Debugging a Class Loader
------------------------

The :class:`Symfony\\Component\\Debug\\DebugClassLoader` attempts to
throw more helpful exceptions when a class isn't found by the registered
autoloaders. All autoloaders that implement a ``findFile()`` method are replaced
with a ``DebugClassLoader`` wrapper.

Using the ``DebugClassLoader`` is done by calling its static
:method:`Symfony\\Component\\Debug\\DebugClassLoader::enable` method::

use Symfony\Component\Debug\DebugClassLoader;
.. deprecated:: 4.4

DebugClassLoader::enable();
In Symfony versions before 4.4, this component also provided error and
exception handlers. In Symfony 4.4 they were deprecated in favor of their
equivalent handlers included in the new :doc:`ErrorHandler component </components/error_handler>`.
94 changes: 94 additions & 0 deletions components/error_handler.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
.. index::
single: Debug
single: Error
single: Exception
single: Components; ErrorHandler

The ErrorHandler Component
==========================

The ErrorHandler component provides tools to manage errors and ease debugging PHP code.

Installation
------------

.. code-block:: terminal

$ composer require symfony/error-handler

.. include:: /components/require_autoload.rst.inc

Usage
-----

The ErrorHandler component provides several tools to help you debug PHP code.
Enable all of them by calling this method::

use Symfony\Component\ErrorHandler\Debug;

Debug::enable();

The :method:`Symfony\\Component\\ErrorHandler\\Debug::enable` method registers an
error handler, an exception handler and
:ref:`a special class loader <component-debug-class-loader>`.

Read the following sections for more information about the different available
tools.

.. caution::

You should never enable the debug tools, except for the error handler, in a
production environment as they might disclose sensitive information to the user.

Handling PHP Errors and Exceptions
----------------------------------

Enabling the Error Handler
~~~~~~~~~~~~~~~~~~~~~~~~~~

The :class:`Symfony\\Component\\ErrorHandler\\ErrorHandler` class catches PHP
errors and converts them to exceptions (of class :phpclass:`ErrorException` or
:class:`Symfony\\Component\\ErrorHandler\\Exception\\FatalErrorException` for
PHP fatal errors)::

use Symfony\Component\ErrorHandler\ErrorHandler;

ErrorHandler::register();

This error handler is enabled by default in the production environment when the
application uses the FrameworkBundle because it generates better error logs.

Enabling the Exception Handler
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The :class:`Symfony\\Component\\ErrorHandler\\ExceptionHandler` class catches
uncaught PHP exceptions and converts them to a nice PHP response. It is useful
in :ref:`debug mode <debug-mode>` to replace the default PHP/XDebug output with
something prettier and more useful::

use Symfony\Component\ErrorHandler\ExceptionHandler;

ExceptionHandler::register();

.. note::

If the :doc:`HttpFoundation component </components/http_foundation>` is
available, the handler uses a Symfony Response object; if not, it falls
back to a regular PHP response.

.. _component-debug-class-loader:

Debugging a Class Loader
------------------------

The :class:`Symfony\\Component\\ErrorHandler\\DebugClassLoader` attempts to
throw more helpful exceptions when a class isn't found by the registered
autoloaders. All autoloaders that implement a ``findFile()`` method are replaced
with a ``DebugClassLoader`` wrapper.

Using the ``DebugClassLoader`` is done by calling its static
:method:`Symfony\\Component\\ErrorHandler\\DebugClassLoader::enable` method::

use Symfony\Component\ErrorHandler\DebugClassLoader;

DebugClassLoader::enable();
160 changes: 160 additions & 0 deletions components/error_renderer.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
.. index::
single: Error
single: Exception
single: Components; ErrorRenderer

The ErrorRenderer Component
===========================

The ErrorRenderer component converts PHP errors and exceptions into other
formats such as JSON and HTML and renders them.

Installation
------------

.. code-block:: terminal

$ composer require symfony/error-renderer

.. include:: /components/require_autoload.rst.inc

Usage
-----

The ErrorRenderer component provides several renderers to convert PHP errors and
exceptions into other formats such as JSON and HTML easier to debug when working
with HTTP applications::

use Symfony\Component\ErrorRenderer\ErrorRenderer;
use Symfony\Component\ErrorRenderer\ErrorRenderer\HtmlErrorRenderer;
use Symfony\Component\ErrorRenderer\ErrorRenderer\JsonErrorRenderer;

$renderers = [
new HtmlErrorRenderer(),
new JsonErrorRenderer(),
// ...
];
$errorRenderer = new ErrorRenderer($renderers);

/** @var Symfony\Component\ErrorRenderer\Exception\FlattenException */
$exception = ...;
/** @var Symfony\Component\HttpFoundation\Request */
$request = ...;

return new Response(
$errorRenderer->render($exception, $request->getPreferredFormat()),
$exception->getStatusCode(),
$exception->getHeaders()
);

Built-in Error Renderers
~~~~~~~~~~~~~~~~~~~~~~~~

This component provides error renderers for the most common needs:

* :class:`Symfony\\Component\\ErrorRenderer\\ErrorRenderer\\HtmlErrorRenderer`
renders errors in HTML format;
* :class:`Symfony\\Component\\ErrorRenderer\\ErrorRenderer\\JsonErrorRenderer`
renders errors in JSON format and it's compliant with the `RFC 7807`_ standard;
* :class:`Symfony\\Component\\ErrorRenderer\\ErrorRenderer\\XmlErrorRenderer`
renders errors in XML and Atom formats. It's compliant with the `RFC 7807`_
standard;
* :class:`Symfony\\Component\\ErrorRenderer\\ErrorRenderer\\TxtErrorRenderer`
renders errors in plain text format.

Adding a Custom Error Renderer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Error renderers are PHP classes that implement the
:class:`Symfony\\Component\\ErrorRenderer\\ErrorRenderer\\ErrorRendererInterface`.
For example, if you need to render errors in `JSON-LD format`_, create this
class anywhere in your project::

namespace App\ErrorRenderer;

use Symfony\Component\ErrorRenderer\ErrorRenderer\ErrorRendererInterface;
use Symfony\Component\ErrorRenderer\Exception\FlattenException;

class JsonLdErrorRenderer implements ErrorRendererInterface
{
private $debug;

public function __construct(bool $debug = true)
{
$this->debug = $debug;
}

public static function getFormat(): string
{
return 'jsonld';
}

public function render(FlattenException $exception): string
{
$content = [
'@id' => 'https://example.com',
'@type' => 'error',
'@context' => [
'title' => $exception->getTitle(),
'code' => $exception->getStatusCode(),
'message' => $exception->getMessage(),
],
];

if ($this->debug) {
$content['@context']['exceptions'] = $exception->toArray();
}

return (string) json_encode($content);
}
}

.. tip::

If the ``getFormat()`` method of your error renderer matches one of formats
supported by the built-in renderers, the built-in renderer is replaced by
your custom renderer.

To enable the new error renderer in the application,
:ref:`register it as a service <service-container-creating-service>` and
:doc:`tag it </service_container/tags>` with the ``error_renderer.renderer``
tag.

.. configuration-block::

.. code-block:: yaml

# config/services.yaml
services:
App\ErrorRenderer\JsonLdErrorRenderer:
arguments: ['%kernel.debug%']
tags: ['error_renderer.renderer']

.. 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>
<service id="App\ErrorRenderer\JsonLdErrorRenderer">
<argument>true</argument>
<tag name="error_renderer.renderer"/>
</service>
</services>
</container>

.. code-block:: php

// config/services.php
use App\ErrorRenderer\JsonLdErrorRenderer;

$container->register(JsonLdErrorRenderer::class)
->setArguments([true]);
->addTag('error_renderer.renderer');

.. _`RFC 7807`: https://tools.ietf.org/html/rfc7807
.. _`JSON-LD format`: https://en.wikipedia.org/wiki/JSON-LD
2 changes: 1 addition & 1 deletion components/http_kernel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ below for more details).
The listener has several goals:

1) The thrown exception is converted into a
:class:`Symfony\\Component\\Debug\\Exception\\FlattenException`
:class:`Symfony\\Component\\ErrorRenderer\\Exception\\FlattenException`
object, which contains all the information about the request, but which
can be printed and serialized.

Expand Down
2 changes: 2 additions & 0 deletions configuration/front_controllers_and_kernel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ new kernel.
.. index::
single: Configuration; Debug mode

.. _debug-mode:

Debug Mode
~~~~~~~~~~

Expand Down
2 changes: 1 addition & 1 deletion controller/error_pages.rst
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ the request that will be dispatched to your controller. In addition, your contro
will be passed two parameters:

``exception``
A :class:`\\Symfony\\Component\\Debug\\Exception\\FlattenException`
A :class:`\\Symfony\\Component\\ErrorRenderer\\Exception\\FlattenException`
instance created from the exception being handled.

``logger``
Expand Down
4 changes: 2 additions & 2 deletions create_framework/http_kernel_httpkernel_class.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Our code is now much more concise and surprisingly more robust and more
powerful than ever. For instance, use the built-in ``ExceptionListener`` to
make your error management configurable::

$errorHandler = function (Symfony\Component\Debug\Exception\FlattenException $exception) {
$errorHandler = function (Symfony\Component\ErrorRenderer\Exception\FlattenException $exception) {
$msg = 'Something went wrong! ('.$exception->getMessage().')';

return new Response($msg, $exception->getStatusCode());
Expand All @@ -91,7 +91,7 @@ The error controller reads as follows::
// example.com/src/Calendar/Controller/ErrorController.php
namespace Calendar\Controller;

use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\ErrorRenderer\Exception\FlattenException;
use Symfony\Component\HttpFoundation\Response;

class ErrorController
Expand Down