Итак, есть проблема: в prod-режиме при возникновении ошибки я вижу ее в журнале ошибок 4 раза.
Выходит это потому, что монолог пишет ее 4 раза (см. ниже), но проблема не в монологе, а в том, кто его вызывает:

Если присмотреться, то ошибку пишет:
Казалось бы, можно отключить \Symfony\Component\ErrorHandler\ErrorHandler - например я переопределил его на свой хендлер-заглушку:
<?php
declare(strict_types=1);
namespace Symfony\Component\ErrorHandler;
/**
* Проблема: при неправильном значении пути к классу в services.yaml мы получаем 4 ошибки об одном и том же, а
* различаются они только тем, что к основной ошибке дописывается какая-нибудь информация, например:
* - "message":"Uncaught PHP Exception Error: \"Class \"YaPro\\SeoBundle\\MyListener\" not found\" at App_KernelProdContainer.php line 257"
* - "message":"Uncaught Error: Class \"YaPro\\SeoBundle\\MyListener\" not found"
* - "message":"Uncaught PHP Exception Symfony\\Component\\ErrorHandler\\Error\\ClassNotFoundError: \"Attempted to load class \"MyListener\" from namespace \"YaPro\\SeoBundle\".\nDid you forget a \"use\" statement for another namespace?\" at App_KernelProdContainer.php line 257"
* - "message":"Uncaught Error: Class \"YaPro\\SeoBundle\\MyListener\" not found"
*
* Решение: подменять хендлер ошибок
*
* Установка производится в конце файла backend/config/autoload.php добавлением строки:
* $composer->addClassMap(["Symfony\Component\ErrorHandler\ErrorHandler" => __DIR__ . "/MyErrorHandler/ErrorHandler.php"]);
*
* Не забываем пересобрать автолоад (а то композер может полагаться на кэш): composer dump-autoload
*/
class ErrorHandler
{
private int $thrownErrors = 0x1FFF; // E_ALL - E_DEPRECATED - E_USER_DEPRECATED
private int $scopedErrors = 0x1FFF; // E_ALL - E_DEPRECATED - E_USER_DEPRECATED
private int $tracedErrors = 0x77FB; // E_ALL - E_STRICT - E_PARSE
private int $screamedErrors = 0x55; // E_ERROR + E_CORE_ERROR + E_COMPILE_ERROR + E_PARSE
public static function register()
{
$handler = new static();
return $handler;
}
public function doNothing()
{
// в случае ошибки обработчик ничего не делает, ведь есть ErrorListener-ры (они как раз пишут логи в json)
}
// вызывается в Http и Console:
public function setDefaultLogger()
{
// native php stderr, but see the description of doNothing()
}
// вызывается в Http и Console:
public function scopeAt(): int
{
return $this->scopedErrors;
}
// вызывается в Http и Console:
public function throwAt(): int
{
return $this->thrownErrors;
}
// вызывается только в Http:
public function screamAt(): int // int $levels, bool $replace = false
{
return $this->screamedErrors;
}
public function setExceptionHandler(): ?callable
{
return null; // я ставил брейкпоинт в этой строке и за месяц работы этот метод ни разу не вызывался
}
}Отлично, отключили, но получаем другую проблему - проблему в php (моя версия падает и печатает объект события, в котором все ENV-переменные со значениями, короче компрометация данных).
Попробуем заставить php не печатать этот объект (вообще не понятно, с чего он взял, что его нужно распечатать):
display_errors = off (не помогает)
display_startup_errors = off (не помогает)
log_errors = off (не помогает)Все, настройки связанные с выводом ошибок закончились - ничего не помогло (php печатает бесконечно большое тело ответа и даже невозможно понять, это stderr или stdout).
Поэтому, делаю вывод:
http_response_code(500);
echo 'Sorry';
exit(123);Если что, вот реализация моего монолог-хендлера.
Комментарии
Комментариев пока нет.