77The ErrorHandler Component
88==========================
99
10- The ErrorHandler component provides tools to manage errors and ease debugging PHP code.
10+ The ErrorHandler component provides tools to manage errors and ease
11+ debugging PHP code.
1112
1213Installation
1314------------
@@ -21,132 +22,149 @@ Installation
2122Usage
2223-----
2324
24- The ErrorHandler component provides several tools to help you debug PHP code.
25- Enable all of them by calling this method::
25+ The ErrorHandler component provides several tools to help you debug PHP code:
2626
27+ * An **error handler ** that turns PHP errors into exceptions;
28+ * An **exception handler ** that turns uncaught PHP exceptions into nice PHP responses;
29+ * A **debug class loader ** that provides better errors when a class is not found.
30+
31+ Call this method (e.g. in your:ref: `front controller <architecture-front-controller >`)
32+ to enable all these features in your application::
33+
34+ // public/index.php
2735 use Symfony\Component\ErrorHandler\Debug;
2836
29- Debug::enable();
37+ if ($_SERVER['APP_DEBUG']) {
38+ Debug::enable();
39+ }
3040
31- The:method: `Symfony\\ Component\\ ErrorHandler\\ Debug::enable ` method registers an
32- error handler, an exception handler and
33- :ref: `a special class loader <component-debug-class-loader >`.
41+ // ...
3442
35- Read the following sections for moreinformation aboutthe different available
36- tools .
43+ Keep reading this article to learn more abouteach feature, including how to
44+ enable each of them separately .
3745
3846..caution ::
3947
4048 You should never enable the debug tools, except for the error handler, in a
4149 production environment as they might disclose sensitive information to the user.
4250
43- Handling PHP Errorsand Exceptions
51+ Turning PHP Errorsinto Exceptions
4452----------------------------------
4553
46- Enabling the Error Handler
47- ~~~~~~~~~~~~~~~~~~~~~~~~~~
48-
4954The:class: `Symfony\\ Component\\ ErrorHandler\\ ErrorHandler ` class catches PHP
50- errors and converts them to exceptions (of class:phpclass: `ErrorException ` or
51- :class: `Symfony\\ Component\\ ErrorHandler\\ Exception\\ FatalErrorException ` for
52- PHP fatal errors)::
53-
54- use Symfony\Component\ErrorHandler\ErrorHandler;
55-
56- ErrorHandler::register();
55+ errors and turns them into PHP's:phpclass: `ErrorException ` objects, except for
56+ fatal PHP errors, which are turned into Symfony's
57+ :class: `Symfony\\ Component\\ ErrorHandler\\ Exception\\ FatalErrorException ` objects.
5758
58- This error handler is enabled by default in the production environment when the
59- application uses the FrameworkBundle because it generates better error logs.
59+ If the application uses the FrameworkBundle, this error handler is enabled by
60+ default in the:ref: `production environment <configuration-environments >`
61+ because it generates better error logs.
6062
61- Enabling theException Handler
62- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63+ Use thefollowing code (e.g. in your :ref: ` front controller < architecture-front-controller >`)
64+ to enable this error handler::
6365
64- The:class: `Symfony\\ Component\\ ErrorHandler\\ ExceptionHandler ` class catches
65- uncaught PHP exceptions and converts them to a nice PHP response. It is useful
66- in:ref: `debug mode <debug-mode >` to replace the default PHP/XDebug output with
67- something prettier and more useful::
68-
69- use Symfony\Component\ErrorHandler\ExceptionHandler;
70-
71- ExceptionHandler::register();
66+ use Symfony\Component\ErrorHandler\ErrorHandler;
7267
73- .. note ::
68+ ErrorHandler::register();
7469
75- If the:doc: `HttpFoundation component </components/http_foundation >` is
76- available, the handler uses a Symfony Response object; if not, it falls
77- back to a regular PHP response.
70+ ..tip ::
7871
79- Catches PHP errors and turn them into exceptions
80- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
72+ If you want to get even better exception pages, install the
73+ :doc: ` ErrorRenderer component < /components/error_renderer >` too.
8174
82- Most PHP core functions were written before exception handling was introduced to the
83- language and most of this functions do not throw an exception on failure. Instead,
84- they return ``false `` in case of error.
75+ Catching PHP Function Errors and Turning Them into Exceptions
76+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8577
86- Let's take the following code example::
78+ Consider the following example::
8779
8880 $data = json_decode(file_get_contents($filename), true);
8981 $data['read_at'] = date($datetimeFormat);
9082 file_put_contents($filename, json_encode($data));
9183
92- All these functions`` file_get_contents ``, `` json_decode ``, `` date ``, `` json_encode ``
93- and `` file_put_contents `` will return ``false `` or ``null ``on error, having to
94- deal with those failures manually ::
84+ Most PHP core functionswere written before exception handling was introduced,
85+ so they return ``false `` or ``null ``in case of error instead of throwing an
86+ exception. That's why you need to add something like these to check for errors ::
9587
9688 $content = @file_get_contents($filename);
9789 if (false === $content) {
9890 throw new \RuntimeException('Could not load file.');
9991 }
92+
93+ // since PHP 7.3 json_decode() defines an option to throw JSON_THROW_ON_ERROR
94+ // but you need to enable that option explicitly
10095 $data = @json_decode($content, true);
10196 if (null === $data) {
10297 throw new \RuntimeException('File does not contain valid JSON.');
10398 }
99+
104100 $datetime = @date($datetimeFormat);
105101 if (false === $datetime) {
106102 throw new \RuntimeException('Invalid datetime format.');
107103 }
108- // ...
109-
110- ..note ::
111-
112- Since PHP 7.3 `json_decode `_ function will accept a new ``JSON_THROW_ON_ERROR `` option
113- that will let ``json_decode `` throw an exception instead of returning ``null `` on error.
114- However, it is not enabled by default, so you will need to explicitly configure it.
115104
116- To simplify this behavior the:class: `Symfony\\ Component\\ ErrorHandler\\ ErrorHandler ` class
117- provides a:method: `Symfony\\ Component\\ ErrorHandler\\ ErrorHandler::call ` method that will
118- automatically throw an exception when such a failure occurs. This method will accept a ``callable ``
119- parameter and then the arguments needed to call it, returning back the result::
105+ To simplify this code, the:class: `Symfony\\ Component\\ ErrorHandler\\ ErrorHandler `
106+ class provides a:method: `Symfony\\ Component\\ ErrorHandler\\ ErrorHandler::call `
107+ method that throws an exception automatically when a PHP error occurs::
120108
121109 $content = ErrorHandler::call('file_get_contents', $filename);
122110
123- This way, you could use a ``\Closure `` function to wrap a portion of code and be sure that it
124- breaks even if the `@-silencing operator `_ is used::
111+ The first argument of ``call() `` is the name of the PHP function to execute and
112+ the rest of arguments are passed to the PHP function. The result of the PHP
113+ function is returned as the result of ``call() ``.
114+
115+ You can pass any PHP callable as the first argument of ``call() ``, so you can
116+ wrap several function calls inside an anonymous function::
125117
126118 $data = ErrorHandler::call(static function () use ($filename, $datetimeFormat) {
119+ // if any code executed inside this anonymous function fails, a PHP exception
120+ // will be thrown, even if the code uses the '@' PHP silence operator
127121 $data = json_decode(file_get_contents($filename), true);
128122 $data['read_at'] = date($datetimeFormat);
129123 file_put_contents($filename, json_encode($data));
130124
131125 return $data;
132126 });
133127
128+ Debugging Uncaught PHP Exceptions
129+ ---------------------------------
130+
131+ The:class: `Symfony\\ Component\\ ErrorHandler\\ ExceptionHandler ` class catches
132+ uncaught PHP exceptions and turns them into a nice response, so you can debug
133+ them. It is useful in:ref: `debug mode <debug-mode >` to replace the default
134+ PHP/XDebug output with something prettier and more useful.
135+
136+ If the:doc: `HttpFoundation component </components/http_foundation >` is
137+ available, the handler returns a Symfony's
138+ :class: `Symfony\\ Component\\ HttpFoundation\\ Response ` object. Otherwise, it returns
139+ a generic PHP response.
140+
141+ Use the following code (e.g. in your:ref: `front controller <architecture-front-controller >`)
142+ to enable this exception handler::
143+
144+ use Symfony\Component\ErrorHandler\ExceptionHandler;
145+
146+ ExceptionHandler::register();
147+
148+ ..tip ::
149+
150+ If you want to get even better exception pages, install the
151+ :doc: `ErrorRenderer component </components/error_renderer >` too.
152+
134153.. _component-debug-class-loader :
135154
136- Debugging a ClassLoader
137- ------------------------
155+ ClassLoading Debugger
156+ ----------------------
138157
139- The:class: `Symfony\\ Component\\ ErrorHandler\\ DebugClassLoader ` attempts to
140- throw more helpful exceptions when a class isn't found by the registered
141- autoloaders. All autoloaders that implement a ``findFile() `` method are replaced
142- with a ``DebugClassLoader `` wrapper.
158+ The:class: `Symfony\\ Component\\ ErrorHandler\\ DebugClassLoader ` class throws
159+ more useful exceptions when a class isn't found by the registered autoloaders
160+ (e.g. looks for typos in the class names and suggest the right class name).
143161
144- Using the ``DebugClassLoader `` is done by calling its static
145- :method: `Symfony\\ Component\\ ErrorHandler\\ DebugClassLoader::enable ` method::
162+ In practice, this debugger looks for all registered autoloaders that implement a
163+ ``findFile() `` method and replaces them by its own method to find class files.
164+
165+ Use the following code (e.g. in your:ref: `front controller <architecture-front-controller >`)
166+ to enable this class loading debugger::
146167
147168 use Symfony\Component\ErrorHandler\DebugClassLoader;
148169
149170 DebugClassLoader::enable();
150-
151- .. _`@-silencing operator` :https://php.net/manual/en/function.json-decode.php
152- .. _`json_decode` :https://php.net/manual/en/language.operators.errorcontrol.php