From b2a1a9b878f1a0fbb62211c9d218cc2d5a5781f4 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 2 Jul 2019 15:06:46 +0200 Subject: [PATCH 1/8] Documented the ErrorCatcher component --- components/debug.rst | 44 +--- components/error_catcher.rst | 205 ++++++++++++++++++ .../front_controllers_and_kernel.rst | 2 + .../http_kernel_httpkernel_class.rst | 4 +- 4 files changed, 214 insertions(+), 41 deletions(-) create mode 100644 components/error_catcher.rst diff --git a/components/debug.rst b/components/debug.rst index 6f116e25af6..b8da5f31d4e 100644 --- a/components/debug.rst +++ b/components/debug.rst @@ -12,7 +12,7 @@ Installation .. code-block:: terminal - $ composer require symfony/debug + $ composer require --dev symfony/debug .. include:: /components/require_autoload.rst.inc @@ -26,50 +26,16 @@ 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 `. - -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:: +.. deprecated:: 4.4 - If the :doc:`HttpFoundation component ` is - available, the handler uses a Symfony Response object; if not, it falls - back to a regular PHP response. + 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:`ErrorCatcher component `. .. _component-debug-class-loader: diff --git a/components/error_catcher.rst b/components/error_catcher.rst new file mode 100644 index 00000000000..a6aa7abd30e --- /dev/null +++ b/components/error_catcher.rst @@ -0,0 +1,205 @@ +.. index:: + single: Error + single: Exception + single: Components; ErrorCatcher + +The ErrorCatcher Component +========================== + + The ErrorCatcher 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-catcher + +.. include:: /components/require_autoload.rst.inc + +Usage +----- + +The ErrorCatcher component provides several handlers and renderers to convert +PHP errors and exceptions into other formats easier to debug when working with +HTTP applications. + +.. TODO: how are these handlers enabled in the app? (Previously: Debug::enable()) + +Handling PHP Errors and Exceptions +---------------------------------- + +Enabling the Error Handler +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :class:`Symfony\\Component\\ErrorCatcher\\ErrorHandler` class catches PHP +errors and converts them to exceptions (of class :phpclass:`ErrorException` or +:class:`Symfony\\Component\\ErrorCatcher\\Exception\\FatalErrorException` for +PHP fatal errors):: + + use Symfony\Component\ErrorCatcher\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\\ErrorCatcher\\ExceptionHandler` class catches +uncaught PHP exceptions and converts them to a nice PHP response. It is useful +in :ref:`debug mode ` to replace the default PHP/XDebug output with +something prettier and more useful:: + + use Symfony\Component\ErrorCatcher\ExceptionHandler; + + ExceptionHandler::register(); + +.. note:: + + If the :doc:`HttpFoundation component ` is + available, the handler uses a Symfony Response object; if not, it falls + back to a regular PHP response. + +Rendering PHP Errors and Exceptions +----------------------------------- + +Another feature provided by this component are the "error renderers", which +converts PHP errors and exceptions into other formats such as JSON and HTML:: + + use Symfony\Component\ErrorHandler\ErrorRenderer\ErrorRenderer; + use Symfony\Component\ErrorHandler\ErrorRenderer\HtmlErrorRenderer; + use Symfony\Component\ErrorHandler\ErrorRenderer\JsonErrorRenderer; + + $renderers = [ + new HtmlErrorRenderer(), + new JsonErrorRenderer(), + // ... + ]; + $errorRenderer = new ErrorRenderer($renderers); + + /** @var Symfony\Component\ErrorHandler\Exception\FlattenException */ + $exception = ...; + /** @var Symfony\Component\HttpFoundation\Request */ + $request = ...; + + return new Response( + $errorRenderer->render($exception, $request->getRequestFormat()), + $exception->getStatusCode(), + $exception->getHeaders() + ); + +Built-in Error Renderers +~~~~~~~~~~~~~~~~~~~~~~~~ + +This component provides error renderers for the most common needs: + + * :class:`Symfony\\Component\\ErrorHandler\\ErrorRenderer\\HtmlErrorRenderer` + renders errors in HTML format; + * :class:`Symfony\\Component\\ErrorHandler\\ErrorRenderer\\JsonErrorRenderer` + renders errors in JsonErrorRenderer format and it's compliant with the + `RFC 7807`_ standard; + * :class:`Symfony\\Component\\ErrorHandler\\ErrorRenderer\\XmlErrorRenderer` + renders errors in XML and Atom formats. It's compliant with the `RFC 7807`_ + standard; + * :class:`Symfony\\Component\\ErrorHandler\\ErrorRenderer\\TxtErrorRenderer` + renders errors in regular text format. + +Adding a Custom Error Renderer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Error renderers are PHP classes that implement the +:class:`Symfony\\Component\\ErrorHandler\\ErrorRenderer\\ErrorRendererInterface`. +For example, if you need to render errors in `JSON-LD format`_, create this +class anywhere in your project:: + + namespace App\ErrorHandler\ErrorRenderer; + + use Symfony\Component\ErrorHandler\ErrorRenderer\ErrorRendererInterface; + use Symfony\Component\ErrorHandler\Exception\FlattenException; + + class JsonLdErrorRenderer implements ErrorRendererInterface + { + private $debug; + + public static function getFormat(): string + { + return 'jsonld'; + } + + public function __construct(bool $debug = true) + { + $this->debug = $debug; + } + + 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 ` and +:doc:`tag it ` with the ``error_handler.renderer`` +tag. + +.. configuration-block:: + + .. code-block:: yaml + + # config/services.yaml + services: + App\ErrorHandler\ErrorRenderer\JsonLdErrorRenderer: + arguments: ['%kernel.debug%'] + tags: ['error_handler.renderer'] + + .. code-block:: xml + + + + + + + + true + + + + + + .. code-block:: php + + // config/services.php + use App\ErrorHandler\ErrorRenderer\JsonLdErrorRenderer; + + $container->register(JsonLdErrorRenderer::class) + ->setArguments([true]); + ->addTag('error_handler.renderer'); + +.. _`RFC 7807`: https://tools.ietf.org/html/rfc7807 +.. _`JSON-LD format`: https://en.wikipedia.org/wiki/JSON-LD diff --git a/configuration/front_controllers_and_kernel.rst b/configuration/front_controllers_and_kernel.rst index d986d7471b7..bdeac5ed93d 100644 --- a/configuration/front_controllers_and_kernel.rst +++ b/configuration/front_controllers_and_kernel.rst @@ -123,6 +123,8 @@ new kernel. .. index:: single: Configuration; Debug mode +.. _debug-mode: + Debug Mode ~~~~~~~~~~ diff --git a/create_framework/http_kernel_httpkernel_class.rst b/create_framework/http_kernel_httpkernel_class.rst index f9f8f16932f..fc4a1149c13 100644 --- a/create_framework/http_kernel_httpkernel_class.rst +++ b/create_framework/http_kernel_httpkernel_class.rst @@ -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\ErrorCatcher\Exception\FlattenException $exception) { $msg = 'Something went wrong! ('.$exception->getMessage().')'; return new Response($msg, $exception->getStatusCode()); @@ -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\ErrorCatcher\Exception\FlattenException; use Symfony\Component\HttpFoundation\Response; class ErrorController From 4e333c17b9fad553da1d11f6539fa8e4a1f851e9 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 3 Jul 2019 10:35:19 +0200 Subject: [PATCH 2/8] Fixes --- components/error_catcher.rst | 47 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/components/error_catcher.rst b/components/error_catcher.rst index a6aa7abd30e..85f0681fa3d 100644 --- a/components/error_catcher.rst +++ b/components/error_catcher.rst @@ -69,24 +69,24 @@ Rendering PHP Errors and Exceptions Another feature provided by this component are the "error renderers", which converts PHP errors and exceptions into other formats such as JSON and HTML:: - use Symfony\Component\ErrorHandler\ErrorRenderer\ErrorRenderer; - use Symfony\Component\ErrorHandler\ErrorRenderer\HtmlErrorRenderer; - use Symfony\Component\ErrorHandler\ErrorRenderer\JsonErrorRenderer; + use Symfony\Component\ErrorCatcher\ErrorRenderer\ErrorRenderer; + use Symfony\Component\ErrorCatcher\ErrorRenderer\HtmlErrorRenderer; + use Symfony\Component\ErrorCatcher\ErrorRenderer\JsonErrorRenderer; $renderers = [ new HtmlErrorRenderer(), new JsonErrorRenderer(), // ... ]; - $errorRenderer = new ErrorRenderer($renderers); + $errorFormatter = new ErrorFormatter($renderers); - /** @var Symfony\Component\ErrorHandler\Exception\FlattenException */ + /** @var Symfony\Component\ErrorCatcher\Exception\FlattenException */ $exception = ...; /** @var Symfony\Component\HttpFoundation\Request */ $request = ...; return new Response( - $errorRenderer->render($exception, $request->getRequestFormat()), + $errorFormatter->render($exception, $request->getRequestFormat()), $exception->getStatusCode(), $exception->getHeaders() ); @@ -96,29 +96,28 @@ Built-in Error Renderers This component provides error renderers for the most common needs: - * :class:`Symfony\\Component\\ErrorHandler\\ErrorRenderer\\HtmlErrorRenderer` + * :class:`Symfony\\Component\\ErrorCatcher\\ErrorRenderer\\HtmlErrorRenderer` renders errors in HTML format; - * :class:`Symfony\\Component\\ErrorHandler\\ErrorRenderer\\JsonErrorRenderer` - renders errors in JsonErrorRenderer format and it's compliant with the - `RFC 7807`_ standard; - * :class:`Symfony\\Component\\ErrorHandler\\ErrorRenderer\\XmlErrorRenderer` + * :class:`Symfony\\Component\\ErrorCatcher\\ErrorRenderer\\JsonErrorRenderer` + renders errors in JSON format and it's compliant with the `RFC 7807`_ standard; + * :class:`Symfony\\Component\\ErrorCatcher\\ErrorRenderer\\XmlErrorRenderer` renders errors in XML and Atom formats. It's compliant with the `RFC 7807`_ standard; - * :class:`Symfony\\Component\\ErrorHandler\\ErrorRenderer\\TxtErrorRenderer` - renders errors in regular text format. + * :class:`Symfony\\Component\\ErrorCatcher\\ErrorRenderer\\TxtErrorRenderer` + renders errors in plain text format. Adding a Custom Error Renderer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Error renderers are PHP classes that implement the -:class:`Symfony\\Component\\ErrorHandler\\ErrorRenderer\\ErrorRendererInterface`. +:class:`Symfony\\Component\\ErrorCatcher\\ErrorRenderer\\ErrorRendererInterface`. For example, if you need to render errors in `JSON-LD format`_, create this class anywhere in your project:: - namespace App\ErrorHandler\ErrorRenderer; + namespace App\ErrorCatcher; - use Symfony\Component\ErrorHandler\ErrorRenderer\ErrorRendererInterface; - use Symfony\Component\ErrorHandler\Exception\FlattenException; + use Symfony\Component\ErrorCatcher\ErrorRenderer\ErrorRendererInterface; + use Symfony\Component\ErrorCatcher\Exception\FlattenException; class JsonLdErrorRenderer implements ErrorRendererInterface { @@ -162,7 +161,7 @@ class anywhere in your project:: To enable the new error renderer in the application, :ref:`register it as a service ` and -:doc:`tag it ` with the ``error_handler.renderer`` +:doc:`tag it ` with the ``error_catcher.renderer`` tag. .. configuration-block:: @@ -171,9 +170,9 @@ tag. # config/services.yaml services: - App\ErrorHandler\ErrorRenderer\JsonLdErrorRenderer: + App\ErrorCatcher\JsonLdErrorRenderer: arguments: ['%kernel.debug%'] - tags: ['error_handler.renderer'] + tags: ['error_catcher.renderer'] .. code-block:: xml @@ -185,9 +184,9 @@ tag. https://symfony.com/schema/dic/services/services-1.0.xsd"> - + true - + @@ -195,11 +194,11 @@ tag. .. code-block:: php // config/services.php - use App\ErrorHandler\ErrorRenderer\JsonLdErrorRenderer; + use App\ErrorCatcher\JsonLdErrorRenderer; $container->register(JsonLdErrorRenderer::class) ->setArguments([true]); - ->addTag('error_handler.renderer'); + ->addTag('error_catcher.renderer'); .. _`RFC 7807`: https://tools.ietf.org/html/rfc7807 .. _`JSON-LD format`: https://en.wikipedia.org/wiki/JSON-LD From b600b3c8c8b880b6a80d86c43ba6eeab91a3af96 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 12 Jul 2019 10:35:47 +0200 Subject: [PATCH 3/8] Renamed ErrorCatcher as ErrorRenderer --- .../{error_catcher.rst => error_renderer.rst} | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) rename components/{error_catcher.rst => error_renderer.rst} (75%) diff --git a/components/error_catcher.rst b/components/error_renderer.rst similarity index 75% rename from components/error_catcher.rst rename to components/error_renderer.rst index 85f0681fa3d..5c14fdac0f5 100644 --- a/components/error_catcher.rst +++ b/components/error_renderer.rst @@ -1,12 +1,12 @@ .. index:: single: Error single: Exception - single: Components; ErrorCatcher + single: Components; ErrorRenderer -The ErrorCatcher Component -========================== +The ErrorRenderer Component +=========================== - The ErrorCatcher component converts PHP errors and exceptions into other + The ErrorRenderer component converts PHP errors and exceptions into other formats such as JSON and HTML and renders them. Installation @@ -14,14 +14,14 @@ Installation .. code-block:: terminal - $ composer require symfony/error-catcher + $ composer require symfony/error-renderer .. include:: /components/require_autoload.rst.inc Usage ----- -The ErrorCatcher component provides several handlers and renderers to convert +The ErrorRenderer component provides several handlers and renderers to convert PHP errors and exceptions into other formats easier to debug when working with HTTP applications. @@ -33,12 +33,12 @@ Handling PHP Errors and Exceptions Enabling the Error Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~ -The :class:`Symfony\\Component\\ErrorCatcher\\ErrorHandler` class catches PHP +The :class:`Symfony\\Component\\ErrorRenderer\\ErrorHandler` class catches PHP errors and converts them to exceptions (of class :phpclass:`ErrorException` or -:class:`Symfony\\Component\\ErrorCatcher\\Exception\\FatalErrorException` for +:class:`Symfony\\Component\\ErrorRenderer\\Exception\\FatalErrorException` for PHP fatal errors):: - use Symfony\Component\ErrorCatcher\ErrorHandler; + use Symfony\Component\ErrorRenderer\ErrorHandler; ErrorHandler::register(); @@ -48,12 +48,12 @@ application uses the FrameworkBundle because it generates better error logs. Enabling the Exception Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The :class:`Symfony\\Component\\ErrorCatcher\\ExceptionHandler` class catches +The :class:`Symfony\\Component\\ErrorRenderer\\ExceptionHandler` class catches uncaught PHP exceptions and converts them to a nice PHP response. It is useful in :ref:`debug mode ` to replace the default PHP/XDebug output with something prettier and more useful:: - use Symfony\Component\ErrorCatcher\ExceptionHandler; + use Symfony\Component\ErrorRenderer\ExceptionHandler; ExceptionHandler::register(); @@ -69,9 +69,9 @@ Rendering PHP Errors and Exceptions Another feature provided by this component are the "error renderers", which converts PHP errors and exceptions into other formats such as JSON and HTML:: - use Symfony\Component\ErrorCatcher\ErrorRenderer\ErrorRenderer; - use Symfony\Component\ErrorCatcher\ErrorRenderer\HtmlErrorRenderer; - use Symfony\Component\ErrorCatcher\ErrorRenderer\JsonErrorRenderer; + use Symfony\Component\ErrorRenderer\ErrorRenderer\ErrorRenderer; + use Symfony\Component\ErrorRenderer\ErrorRenderer\HtmlErrorRenderer; + use Symfony\Component\ErrorRenderer\ErrorRenderer\JsonErrorRenderer; $renderers = [ new HtmlErrorRenderer(), @@ -80,7 +80,7 @@ converts PHP errors and exceptions into other formats such as JSON and HTML:: ]; $errorFormatter = new ErrorFormatter($renderers); - /** @var Symfony\Component\ErrorCatcher\Exception\FlattenException */ + /** @var Symfony\Component\ErrorRenderer\Exception\FlattenException */ $exception = ...; /** @var Symfony\Component\HttpFoundation\Request */ $request = ...; @@ -96,28 +96,28 @@ Built-in Error Renderers This component provides error renderers for the most common needs: - * :class:`Symfony\\Component\\ErrorCatcher\\ErrorRenderer\\HtmlErrorRenderer` + * :class:`Symfony\\Component\\ErrorRenderer\\ErrorRenderer\\HtmlErrorRenderer` renders errors in HTML format; - * :class:`Symfony\\Component\\ErrorCatcher\\ErrorRenderer\\JsonErrorRenderer` + * :class:`Symfony\\Component\\ErrorRenderer\\ErrorRenderer\\JsonErrorRenderer` renders errors in JSON format and it's compliant with the `RFC 7807`_ standard; - * :class:`Symfony\\Component\\ErrorCatcher\\ErrorRenderer\\XmlErrorRenderer` + * :class:`Symfony\\Component\\ErrorRenderer\\ErrorRenderer\\XmlErrorRenderer` renders errors in XML and Atom formats. It's compliant with the `RFC 7807`_ standard; - * :class:`Symfony\\Component\\ErrorCatcher\\ErrorRenderer\\TxtErrorRenderer` + * :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\\ErrorCatcher\\ErrorRenderer\\ErrorRendererInterface`. +: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\ErrorCatcher; + namespace App\ErrorRenderer; - use Symfony\Component\ErrorCatcher\ErrorRenderer\ErrorRendererInterface; - use Symfony\Component\ErrorCatcher\Exception\FlattenException; + use Symfony\Component\ErrorRenderer\ErrorRenderer\ErrorRendererInterface; + use Symfony\Component\ErrorRenderer\Exception\FlattenException; class JsonLdErrorRenderer implements ErrorRendererInterface { @@ -170,7 +170,7 @@ tag. # config/services.yaml services: - App\ErrorCatcher\JsonLdErrorRenderer: + App\ErrorRenderer\JsonLdErrorRenderer: arguments: ['%kernel.debug%'] tags: ['error_catcher.renderer'] @@ -184,7 +184,7 @@ tag. https://symfony.com/schema/dic/services/services-1.0.xsd"> - + true @@ -194,7 +194,7 @@ tag. .. code-block:: php // config/services.php - use App\ErrorCatcher\JsonLdErrorRenderer; + use App\ErrorRenderer\JsonLdErrorRenderer; $container->register(JsonLdErrorRenderer::class) ->setArguments([true]); From b0723efba53b3484d373495e8becc53986d6bdeb Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 12 Jul 2019 10:36:36 +0200 Subject: [PATCH 4/8] Fixed a method name --- components/error_renderer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/error_renderer.rst b/components/error_renderer.rst index 5c14fdac0f5..89a7e99a4b5 100644 --- a/components/error_renderer.rst +++ b/components/error_renderer.rst @@ -155,7 +155,7 @@ class anywhere in your project:: .. tip:: - If the ``getformat()`` method of your error renderer matches one of formats + 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. From 5136a17136db054af3919c2ab588635a29c0a536 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Fri, 16 Aug 2019 10:00:33 -0400 Subject: [PATCH 5/8] Update with latest changes: ErrorRenderer and ErrorHandler components --- components/debug.rst | 19 +--- components/error_handler.rst | 94 +++++++++++++++++++ components/error_renderer.rst | 72 +++----------- components/http_kernel.rst | 2 +- controller/error_pages.rst | 2 +- .../http_kernel_httpkernel_class.rst | 4 +- 6 files changed, 113 insertions(+), 80 deletions(-) create mode 100644 components/error_handler.rst diff --git a/components/debug.rst b/components/debug.rst index b8da5f31d4e..ceeaf505cce 100644 --- a/components/debug.rst +++ b/components/debug.rst @@ -35,21 +35,4 @@ Enable all of them by calling this method:: 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:`ErrorCatcher component `. - -.. _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; - - DebugClassLoader::enable(); + equivalent handlers included in the new :doc:`ErrorHandler component `. diff --git a/components/error_handler.rst b/components/error_handler.rst new file mode 100644 index 00000000000..59240953a25 --- /dev/null +++ b/components/error_handler.rst @@ -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 `. + +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 ` 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 ` 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(); diff --git a/components/error_renderer.rst b/components/error_renderer.rst index 89a7e99a4b5..001364aa622 100644 --- a/components/error_renderer.rst +++ b/components/error_renderer.rst @@ -21,55 +21,11 @@ Installation Usage ----- -The ErrorRenderer component provides several handlers and renderers to convert -PHP errors and exceptions into other formats easier to debug when working with -HTTP applications. +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:: -.. TODO: how are these handlers enabled in the app? (Previously: Debug::enable()) - -Handling PHP Errors and Exceptions ----------------------------------- - -Enabling the Error Handler -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The :class:`Symfony\\Component\\ErrorRenderer\\ErrorHandler` class catches PHP -errors and converts them to exceptions (of class :phpclass:`ErrorException` or -:class:`Symfony\\Component\\ErrorRenderer\\Exception\\FatalErrorException` for -PHP fatal errors):: - - use Symfony\Component\ErrorRenderer\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\\ErrorRenderer\\ExceptionHandler` class catches -uncaught PHP exceptions and converts them to a nice PHP response. It is useful -in :ref:`debug mode ` to replace the default PHP/XDebug output with -something prettier and more useful:: - - use Symfony\Component\ErrorRenderer\ExceptionHandler; - - ExceptionHandler::register(); - -.. note:: - - If the :doc:`HttpFoundation component ` is - available, the handler uses a Symfony Response object; if not, it falls - back to a regular PHP response. - -Rendering PHP Errors and Exceptions ------------------------------------ - -Another feature provided by this component are the "error renderers", which -converts PHP errors and exceptions into other formats such as JSON and HTML:: - - use Symfony\Component\ErrorRenderer\ErrorRenderer\ErrorRenderer; + use Symfony\Component\ErrorRenderer\ErrorRenderer; use Symfony\Component\ErrorRenderer\ErrorRenderer\HtmlErrorRenderer; use Symfony\Component\ErrorRenderer\ErrorRenderer\JsonErrorRenderer; @@ -78,7 +34,7 @@ converts PHP errors and exceptions into other formats such as JSON and HTML:: new JsonErrorRenderer(), // ... ]; - $errorFormatter = new ErrorFormatter($renderers); + $errorRenderer = new ErrorRenderer($renderers); /** @var Symfony\Component\ErrorRenderer\Exception\FlattenException */ $exception = ...; @@ -86,7 +42,7 @@ converts PHP errors and exceptions into other formats such as JSON and HTML:: $request = ...; return new Response( - $errorFormatter->render($exception, $request->getRequestFormat()), + $errorRenderer->render($exception, $request->getPreferredFormat()), $exception->getStatusCode(), $exception->getHeaders() ); @@ -123,14 +79,14 @@ class anywhere in your project:: { private $debug; - public static function getFormat(): string + public function __construct(bool $debug = true) { - return 'jsonld'; + $this->debug = $debug; } - public function __construct(bool $debug = true) + public static function getFormat(): string { - $this->debug = $debug; + return 'jsonld'; } public function render(FlattenException $exception): string @@ -161,7 +117,7 @@ class anywhere in your project:: To enable the new error renderer in the application, :ref:`register it as a service ` and -:doc:`tag it ` with the ``error_catcher.renderer`` +:doc:`tag it ` with the ``error_renderer.renderer`` tag. .. configuration-block:: @@ -172,7 +128,7 @@ tag. services: App\ErrorRenderer\JsonLdErrorRenderer: arguments: ['%kernel.debug%'] - tags: ['error_catcher.renderer'] + tags: ['error_renderer.renderer'] .. code-block:: xml @@ -186,7 +142,7 @@ tag. true - + @@ -198,7 +154,7 @@ tag. $container->register(JsonLdErrorRenderer::class) ->setArguments([true]); - ->addTag('error_catcher.renderer'); + ->addTag('error_renderer.renderer'); .. _`RFC 7807`: https://tools.ietf.org/html/rfc7807 .. _`JSON-LD format`: https://en.wikipedia.org/wiki/JSON-LD diff --git a/components/http_kernel.rst b/components/http_kernel.rst index 2b2ebe3b5fc..93da3f6156e 100644 --- a/components/http_kernel.rst +++ b/components/http_kernel.rst @@ -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. diff --git a/controller/error_pages.rst b/controller/error_pages.rst index a4026b75a66..482ba6edd95 100644 --- a/controller/error_pages.rst +++ b/controller/error_pages.rst @@ -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`` diff --git a/create_framework/http_kernel_httpkernel_class.rst b/create_framework/http_kernel_httpkernel_class.rst index fc4a1149c13..5845f4219dc 100644 --- a/create_framework/http_kernel_httpkernel_class.rst +++ b/create_framework/http_kernel_httpkernel_class.rst @@ -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\ErrorCatcher\Exception\FlattenException $exception) { + $errorHandler = function (Symfony\Component\ErrorRenderer\Exception\FlattenException $exception) { $msg = 'Something went wrong! ('.$exception->getMessage().')'; return new Response($msg, $exception->getStatusCode()); @@ -91,7 +91,7 @@ The error controller reads as follows:: // example.com/src/Calendar/Controller/ErrorController.php namespace Calendar\Controller; - use Symfony\Component\ErrorCatcher\Exception\FlattenException; + use Symfony\Component\ErrorRenderer\Exception\FlattenException; use Symfony\Component\HttpFoundation\Response; class ErrorController From 5a025c9c037085a7cb3177ae97398386522b76fb Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Sat, 17 Aug 2019 10:00:51 -0400 Subject: [PATCH 6/8] fix example --- components/error_renderer.rst | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/components/error_renderer.rst b/components/error_renderer.rst index 001364aa622..acf379f8741 100644 --- a/components/error_renderer.rst +++ b/components/error_renderer.rst @@ -28,6 +28,8 @@ 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(), @@ -36,16 +38,13 @@ with HTTP applications:: ]; $errorRenderer = new ErrorRenderer($renderers); - /** @var Symfony\Component\ErrorRenderer\Exception\FlattenException */ - $exception = ...; - /** @var Symfony\Component\HttpFoundation\Request */ - $request = ...; + try { + // ... + } catch (\Throwable $e) { + $e = FlattenException::createFromThrowable($e); - return new Response( - $errorRenderer->render($exception, $request->getPreferredFormat()), - $exception->getStatusCode(), - $exception->getHeaders() - ); + return new Response($errorRenderer->render($e, 'json'), 500, ['Content-Type' => 'application/json']); + } Built-in Error Renderers ~~~~~~~~~~~~~~~~~~~~~~~~ From 3ea9817cd68b34c76b2ee1047c95dede54cc5a14 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Sat, 17 Aug 2019 10:05:09 -0400 Subject: [PATCH 7/8] fix service definition --- components/error_renderer.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/error_renderer.rst b/components/error_renderer.rst index acf379f8741..c62fd39c117 100644 --- a/components/error_renderer.rst +++ b/components/error_renderer.rst @@ -140,7 +140,7 @@ tag. - true + %kernel.debug% @@ -152,7 +152,7 @@ tag. use App\ErrorRenderer\JsonLdErrorRenderer; $container->register(JsonLdErrorRenderer::class) - ->setArguments([true]); + ->setArguments([$container->getParameter('kernel.debug')]); ->addTag('error_renderer.renderer'); .. _`RFC 7807`: https://tools.ietf.org/html/rfc7807 From 8cc084f70eb5bbea234771fe990ea0a4415898ce Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Mon, 19 Aug 2019 15:48:12 -0400 Subject: [PATCH 8/8] documenting the ErrorHandler::call method --- components/error_handler.rst | 58 ++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/components/error_handler.rst b/components/error_handler.rst index 59240953a25..e394ece0f4f 100644 --- a/components/error_handler.rst +++ b/components/error_handler.rst @@ -76,6 +76,61 @@ something prettier and more useful:: 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 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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 @@ -92,3 +147,6 @@ Using the ``DebugClassLoader`` is done by calling its static 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 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy