Skip to content

Commit 8cc084f

Browse files
committed
documenting the ErrorHandler::call method
1 parent 3ea9817 commit 8cc084f

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

components/error_handler.rst

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,61 @@ something prettier and more useful::
7676
available, the handler uses a Symfony Response object; if not, it falls
7777
back to a regular PHP response.
7878

79+
Catches PHP errors and turn them into exceptions
80+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
81+
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.
85+
86+
Let's take the following code example::
87+
88+
$data = json_decode(file_get_contents($filename), true);
89+
$data['read_at'] = date($datetimeFormat);
90+
file_put_contents($filename, json_encode($data));
91+
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::
95+
96+
$content = @file_get_contents($filename);
97+
if (false === $content) {
98+
throw new \RuntimeException('Could not load file.');
99+
}
100+
$data = @json_decode($content, true);
101+
if (null === $data) {
102+
throw new \RuntimeException('File does not contain valid JSON.');
103+
}
104+
$datetime = @date($datetimeFormat);
105+
if (false === $datetime) {
106+
throw new \RuntimeException('Invalid datetime format.');
107+
}
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.
115+
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::
120+
121+
$content = ErrorHandler::call('file_get_contents', $filename);
122+
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::
125+
126+
$data = ErrorHandler::call(static function () use ($filename, $datetimeFormat) {
127+
$data = json_decode(file_get_contents($filename), true);
128+
$data['read_at'] = date($datetimeFormat);
129+
file_put_contents($filename, json_encode($data));
130+
131+
return $data;
132+
});
133+
79134
.. _component-debug-class-loader:
80135

81136
Debugging a Class Loader
@@ -92,3 +147,6 @@ Using the ``DebugClassLoader`` is done by calling its static
92147
use Symfony\Component\ErrorHandler\DebugClassLoader;
93148

94149
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

0 commit comments

Comments
 (0)