Description
related with #5428
Q | A |
---|---|
PHPUnit version | 10.4.2 |
PHP version | 8.2.12 |
Installation Method | Composer |
Summary
Current behavior
error_get_last()
is not set when errors are logged (PHPUnit error handler is active). The errors are logged by default which is a good. But the current impl. of the error handler causes code that relies on error_get_last()
set after a core php function has returned a failure like:
$dirHandle = opendir($dirPath);
if ($dirHandle === false) {
$errorMessage = preg_replace('~^.+?:\s*~s', '', error_get_last()['message']);
}
to fail as error_get_last()
is empty.
This is because the current impl. of the error handler returns true
[1] when an error is handled. The php docs say [2]:
It is important to remember that the standard PHP error handler is completely bypassed for the error types specified by error_levels unless the callback function returns false.
[1] https://github.com/sebastianbergmann/phpunit/blob/10.4.2/src/Runner/ErrorHandler.php#L144
[2] https://www.php.net/manual/en/function.set-error-handler.php
The issue is present since PHPUnit 10, in PHPUnit 9 and lower error_get_last()
was set correctly.
How to reproduce
$dirHandle = opendir('/--non-existing-path--');
self::assertNotNull(error_get_last());
Expected behavior
The PHPUnit handler should:
- log an error
- suppress its output
- not affect the
error_get_last()
result, the result must be the same /w and /wo PHPUnit error handler active
I tried to workaround about this issue https://3v4l.org/kS1vM/rfc#vgit.master but if the output is suppressed by lowering the reporting level when handling the error, it seems there is no way to restore the level back immediatelly after the error handling is finished.
I belive the solution is to modify the PHPUnit error handler:
- to return
false
when handling the error - it will let php to handle the error natively - to backup the current
error_reporting()
level and set it toerror_reporting(error_reporting() & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING))
when the handler activates (the listed error levels cannot be handled by an user handler [2]) - to restore the backed error level when the error handler deactivates (or better increase the current error level if lower than the backed one)
- e676667 original fix and c2c8dbb can be reverted then, no
WithoutErrorHandler
attribute needed