Мне предложили отказаться от set_error_handler(), set_exception_handler(), register_shutdown_function() в пользу Throwable(), КОТОРЫЙ ТИПА ЛОВИТ ВСЁ, тестирую: PHP: <?php use core\Test; chdir(dirname(__DIR__)); spl_autoload_register(function ($class) { $file = str_replace('\\', '/', $class) . '.php'; if (is_file($file)) { require_once $file; } }); try { new Test(); // class Test{use test;} } catch (Throwable $throwable) { echo 'Ошибка: ' . $throwable->getMessage(); } Результат: Fatal error: Trait 'core\test' not found Как видим НЕ ЛОВИТ ОН ВСЁ и несуществующий трейт, попал в НЕПЕРЕХВАЧЕННУЮ данным интерфейсом фатальную ошибку, которую я лично, ловлю в register_shutdown_function(). Может я чего-то не понял в Throwable и там есть какой-то секрет для отлова ФАТАЛЬНОЙ ошибки ну вот хотя бы несуществующего трейта?
Такие ошибки перехватываются, насколько я помню, при включении файлов. А вообще, вот именно такие - хай вываливаются фатальными, нафиг их перехватывать? Если я подключил несуществующий трейт, я хочу об этом узнать как можно раньше.
@mkramer, сообщение моё два раза напечаталось я удалил одно, но удалилось два, лень набирать заново, восстановить можно?
не успев зайти, как мысль первая прилетела про сравнивание Exception с Throwable ... PHP: try { // Code that may throw an Exception or Error. } catch (Throwable $t) { // Executed only in PHP 7, will not match in PHP 5.x } catch (Exception $e) { // Executed only in PHP 5.x, will not be reached in PHP 7 } После почитав, понял суть. Тут для ознакомления в актуал PHP https://sergeymukhin.com/blog/sovremennaya-obrabotka-oshibok-v-php
@MouseZver, ничего он там нового не написал, если честно, пару дней назад читал зря время потратил, видимо придётся оставить как есть PHP: <?php namespace core; use Throwable; class Debug { public static function run() { ob_start(); set_error_handler([self::class, 'errorHandler']); set_exception_handler([self::class, 'exceptionHandler']); register_shutdown_function([self::class, 'uncaughtErrorHandler']); } public static function errorHandler($code, $text, $file, $line) { self::displayError('Ошибка', $code, $text, $file, $line); } private static function displayError($head, $code, $text, $file, $line) { ob_end_clean(); if ($code != 404) { $code = 500; } http_response_code($code); if (App::$debug) { require_once 'app/views/layouts/errors/displayError.php'; } else { self::logError($head, $code, $text, $file, $line); require_once "app/views/layouts/errors/{$code}.html"; } die(); } private static function logError($head, $code, $text, $file, $line) { $date = date('d-m-Y'); $time = date('H:i:s'); $bash = str_repeat('-', 120); $log_text = "[{$time} - {$head}]\nТекст: {$text}\nФайл: {$file}\nСтрока: {$line}\n{$bash}\n"; $log_file = "tmp/errors/{$code}/{$date}.log"; error_log($log_text, 3, $log_file); } public static function exceptionHandler(Throwable $e) { self::displayError('Исключение', $e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine()); } public static function uncaughtErrorHandler() { $e = error_get_last(); if ($e) { self::displayError('Неперехваченная ошибка', $e['type'], $e['message'], $e['file'], $e['line']); } } } вот так несуществующий трейт тогда попадёт в Неперехваченные и обработается, как ожидалось
если желаешь перехватывать ошибки на низком уровне компиляции, то да - set_error_handler не все, но умеет дополнительно кастомизировать ошибки. Я в начале своего пути по php тоже что-то подобное пилил. После осмыслил - а нахрена ?
@MouseZver, set_error_handler не ловит несуществующий трейт - это неперехваченная ошибка, нужно в error_get_last её искать через register_shutdown_function, у меня просто админу и пользователю разные страницы (виды) отдаются при срабатывании глобального обработчика ошибок: админу - трассировка, пользователю - 404 я просто хотел избавиться от громоздкого дебаггера и сделать всё одним try-catch с помощью Throwable, но вот этот ОДИН неотловленный трей портит мне всё настроение (хотя других пока что косяков в нём не нашёл)
тобишь у тебя не пишет текст, заданный тобой об таком то ошибке? --- Добавлено --- Я просто на данный момент знаю, что не все ошибки ловятся и можно на свой лад переделать
@MouseZver, это не пользовательские исключения, для своих исключения я могу понаделать своих классов, реализующих Throwable и выдавать юзерам всякую ерунду разноцветную с эти текстом, НО мне нужно при глобальном выбросе принять решение кому что показать, Throwable при несуществующем трейте не сделает выброс, нужно error_get_last задействовать и оттуда доставать неперехваченную несуществующего трейта