Fatal error на production: как искать причину без вывода ошибок
Fatal error на production часто выглядит как белый экран, 500 ошибка или пустой ответ. Пользователь видит проблему, но разработчику нельзя просто включить display_errors и показать трассировку всему интернету. Диагностика должна идти через логи и безопасные временные инструменты.
Главная задача — найти точную ошибку и файл, не раскрывая внутренности проекта пользователям.
Не включать display_errors на production
Показ ошибок в браузере может раскрыть пути на сервере, структуру проекта, SQL, имена классов, токены и другие технические детали. На production ошибки должны писаться в лог.
display_errors = Off
log_errors = On
error_reporting = E_ALL
После изменения php.ini нужно перезапустить PHP-FPM или соответствующий сервис.
sudo systemctl restart php8.2-fpm
Проверить PHP error log
Первое место для поиска fatal error — PHP error log. Путь зависит от сервера и PHP-FPM pool.
tail -n 150 /var/log/php-fpm/error.log
tail -n 150 /var/log/php8.2-fpm.log
tail -n 150 /var/log/php/error.log
Если путь неизвестен, его можно искать в конфигурации:
php -i | grep error_log
grep -R "php_admin_value\[error_log\]" /etc/php/*/fpm/pool.d/
Проверить nginx или Apache
Если запрос не дошёл до PHP, PHP-лог может быть пустым. Тогда нужно смотреть веб-сервер.
tail -n 150 /var/log/nginx/error.log
tail -n 150 /var/log/nginx/access.log
В access.log полезно найти конкретный проблемный URL и код ответа.
grep "/problem-page/" /var/log/nginx/access.log | tail
Последние изменения
Fatal error часто появляется после деплоя, обновления Composer, изменения PHP-версии или ручной правки файла. Нужно быстро понять, что менялось.
git log --oneline -5
git diff HEAD~1..HEAD
find . -name "*.php" -mtime -1 -print
Если проект без git, задача сложнее. Тогда особенно важны бэкапы и журнал изменений.
Проверить синтаксис PHP-файлов
Если есть подозрение на синтаксическую ошибку, можно проверить изменённые файлы через php -l.
php -l path/to/file.php
Для проекта целиком:
find local app modules -name "*.php" -print0 | xargs -0 -n1 php -l
Команду нужно адаптировать под структуру проекта, чтобы не проверять vendor без необходимости.
OPcache
Иногда код уже исправили, но сервер продолжает выполнять старую версию из OPcache. Особенно если validate_timestamps отключён или настроен большой revalidate_freq.
php -i | grep opcache.validate_timestamps
php -i | grep opcache.revalidate_freq
Для быстрой проверки можно перезапустить PHP-FPM.
sudo systemctl restart php8.2-fpm
Shutdown handler
Если в проекте трудно поймать fatal error, можно временно добавить shutdown handler, который пишет последнюю ошибку в отдельный лог.
register_shutdown_function(function () {
$error = error_get_last();
if ($error !== null) {
error_log(json_encode([
'type' => $error['type'],
'message' => $error['message'],
'file' => $error['file'],
'line' => $error['line'],
], JSON_UNESCAPED_UNICODE));
}
});
Такой код нужно использовать аккуратно и не превращать в постоянный шумный лог.
Права на логи
Иногда ошибка есть, но приложение не может записать лог. После переноса или деплоя нужно проверить директории логов.
ls -la runtime/logs
ls -la var/log
touch runtime/logs/test.log
Чек-лист
- Не включать display_errors для пользователей.
- Проверить PHP error log.
- Проверить nginx или Apache error log.
- Найти проблемный URL в access.log.
- Проверить последние изменения кода.
- Проверить синтаксис изменённых PHP-файлов.
- Проверить Composer и autoload, если менялись зависимости.
- Проверить OPcache после исправления.
- Проверить права на директории логов.
Fatal error на production нужно искать через наблюдаемые следы: логи, последние изменения, синтаксис, зависимости и окружение. Чем лучше настроено логирование, тем меньше соблазн включать опасный вывод ошибок на рабочем сайте.
Комментарии (0)
Пока нет комментариев. Будьте первым!