Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork5.3k
Documenting ErrorRenderer and ErrorHandler components#12187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
b2a1a9b4e333c1b600b3cb0723ef5136a175a025c93ea98178cc084fFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| .. 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. | ||
| Catches PHP errors and turn them into exceptions | ||
MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. btw, documentingsymfony/symfony#33155, close#12193 | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| Most PHP core functions were written before exception handling was introduced to the | ||
| language and most of this functions do not throw an exception on failure. Instead, | ||
| they return ``false`` in case of error. | ||
| Let's take the following code example:: | ||
| $data = json_decode(file_get_contents($filename), true); | ||
| $data['read_at'] = date($datetimeFormat); | ||
| file_put_contents($filename, json_encode($data)); | ||
| All these functions ``file_get_contents``, ``json_decode``, ``date``, ``json_encode`` | ||
| and ``file_put_contents`` will return ``false`` or ``null`` on error, having to | ||
| deal with those failures manually:: | ||
| $content = @file_get_contents($filename); | ||
| if (false === $content) { | ||
| throw new \RuntimeException('Could not load file.'); | ||
| } | ||
| $data = @json_decode($content, true); | ||
| if (null === $data) { | ||
| throw new \RuntimeException('File does not contain valid JSON.'); | ||
| } | ||
| $datetime = @date($datetimeFormat); | ||
| if (false === $datetime) { | ||
| throw new \RuntimeException('Invalid datetime format.'); | ||
| } | ||
| // ... | ||
| .. note:: | ||
| Since PHP 7.3 `json_decode`_ function will accept a new ``JSON_THROW_ON_ERROR`` option | ||
| that will let ``json_decode`` throw an exception instead of returning ``null`` on error. | ||
| However, it is not enabled by default, so you will need to explicitly configure it. | ||
| To simplify this behavior the :class:`Symfony\\Component\\ErrorHandler\\ErrorHandler` class | ||
| provides a :method:`Symfony\\Component\\ErrorHandler\\ErrorHandler::call` method that will | ||
| automatically throw an exception when such a failure occurs. This method will accept a ``callable`` | ||
| parameter and then the arguments needed to call it, returning back the result:: | ||
| $content = ErrorHandler::call('file_get_contents', $filename); | ||
| This way, you could use a ``\Closure`` function to wrap a portion of code and be sure that it | ||
| breaks even if the `@-silencing operator`_ is used:: | ||
| $data = ErrorHandler::call(static function () use ($filename, $datetimeFormat) { | ||
| $data = json_decode(file_get_contents($filename), true); | ||
| $data['read_at'] = date($datetimeFormat); | ||
| file_put_contents($filename, json_encode($data)); | ||
| return $data; | ||
| }); | ||
| .. _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(); | ||
| .. _`@-silencing operator`: https://php.net/manual/en/function.json-decode.php | ||
| .. _`json_decode`: https://php.net/manual/en/language.operators.errorcontrol.php | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| .. 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; | ||
| use Symfony\Component\ErrorRenderer\Exception\FlattenException; | ||
| use Symfony\Component\HttpFoundation\Response; | ||
| $renderers = [ | ||
| new HtmlErrorRenderer(), | ||
| new JsonErrorRenderer(), | ||
| // ... | ||
| ]; | ||
| $errorRenderer = new ErrorRenderer($renderers); | ||
| try { | ||
| // ... | ||
| } catch (\Throwable $e) { | ||
| $e = FlattenException::createFromThrowable($e); | ||
| return new Response($errorRenderer->render($e, 'json'), 500, ['Content-Type' => 'application/json']); | ||
| } | ||
| 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>%kernel.debug%</argument> | ||
| <tag name="error_renderer.renderer"/> | ||
| </service> | ||
| </services> | ||
| </container> | ||
| .. code-block:: php | ||
| // config/services.php | ||
| use App\ErrorRenderer\JsonLdErrorRenderer; | ||
| $container->register(JsonLdErrorRenderer::class) | ||
| ->setArguments([$container->getParameter('kernel.debug')]); | ||
| ->addTag('error_renderer.renderer'); | ||
| .. _`RFC 7807`: https://tools.ietf.org/html/rfc7807 | ||
| .. _`JSON-LD format`: https://en.wikipedia.org/wiki/JSON-LD |
Uh oh!
There was an error while loading.Please reload this page.