|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2015-10-11 03:34 UTC] yajenyak at yandex dot ru
Description: ------------ When the ErrorException is thrown in the error handler registered with set_error_handler() the exception handler is not called but the next line in the code is executed which not should happend because the exception handler must be called. I can't provide exact chunk of the code because the error is not reproducable without context, but the code that I will provide causes the bug happen in the context. This bug may be related with the https://bugs.php.net/bug.php?id=70210 but I don't have enough knowledge of the PHP internals for now to make conclusions. Test script: --------------- // This error code doesn't reproduce the error without context code, but it shows when the bug happens: class MyHandler { public function handleException(\Throwable $e) { die('This line WILL NOT be called!'); } public function handleError($errno, $errstr, $errfile, $errline, $context) { if ($errno && error_reporting()) { // This line should cause the MyHandler::handleException() be called // but the the die() in the $myCallback is executed instead, // it should not happen! throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); } } public function handleError($errno, $errstr, $errfile, $errline, $context) { die('called'); } } error_reporting(E_ALL | E_STRICT); ini_set('display_errors', 1); $myHandler = new MyHandler; set_error_handler([$myHandler, 'handleError']); set_exception_handler([$myHandler, 'handleException']); register_shutdown_function([$myHandler, 'shutdown']); // ------------------------ // In some method of some class: class MySomeClass { // ... public function doSomething() { // ... $myCallback = function ($name) { die('This line WILL be executed!'); }; foreach ($collection as $item) { // ... try { // Trigger error - E_WARNING $res = $myCallback(); } catch (\Throwable $e) { die('This line WILL NOT be executed'); } die('This line WILL NOT be executed'); // ... // ... } Expected result: ---------------- Calling of the MyHandler::handleException() Actual result: -------------- The die() function is called here: $myCallback = function ($name) { die('This line WILL be executed!'); }; PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Nov 08 22:00:01 2025 UTC |
Really need that repro script because as far as I can tell from that code, it should not repro your problem. Which is what you said is the case. But it looks like what you've given should be close? By the way, there's a bug in your code: if ($errno && error_reporting()) { That's a boolean &&. What the expression does is check that $errno != 0 (the expression was not @-silenced) and that error_reporting() != 0. What you should be doing is checking that the error_reporting() bitmask has the $errno bit set - using the bitwise &. An easy mistake/typo to make. if ($errno & error_reporting()) {Thank you for you comment. I able to reproduce the bug, here is a code: <?php class MyHandler { public function handleException(\Throwable $e) { die('This line WILL NOT be called!'); } public function handleError($errno, $errstr, $errfile, $errline, $context) { if ($errno & error_reporting()) { // This line should cause the MyHandler::handleException() be called // but the the die() in the $myCallback is executed instead, // it should not happen! throw new \ErrorException($errstr, 0, $errno, $errfile, $errline); } } public function shutdown() { die("\n" . __METHOD__ . ' called'); } } error_reporting(E_ALL | E_STRICT); ini_set('display_errors', 1); $myHandler = new MyHandler; set_error_handler([$myHandler, 'handleError']); set_exception_handler([$myHandler, 'handleException']); register_shutdown_function([$myHandler, 'shutdown']); // ------------------------ // In some method of some class: class MySomeClass { public function test() { $method = 'doSomething'; $res = $this->$method(); } public function doSomething() { // ... $myCallback = function ($name) { die('This line WILL be executed!'); }; foreach (['a', 'b', 'c'] as $item) { // ... try { // Trigger error - E_WARNING $res = $myCallback(); } catch (\Throwable $e) { die('This line WILL NOT be executed'); } die('This line WILL NOT be executed'); } } } $instance = new MySomeClass(); $instance->doSomething(); ------------------------------------------------------------- Part of the output is: This line WILL be executed!PHP Fatal error: Uncaught ErrorException: Missing argument 1 for MySomeClass::{closure}(), called in ... on line 44 and defined... ...