Цель: отобразить в консоли выброшенное исключение в json-представлении
Протестируем, как работает казавшаяся правильным конфигурация:

Как видим, появляются 2 сообщения:
Нас это не устраивает, попробуем включить как советуют в документации:

Как видим, появляются 3 сообщения:
Нас это не устраивает, из monolog.yaml убираем handler с именем console.
Console\Application в случае выброса исключения в коде, пишет о проблеме 2 раза с такой последовательностью:
1. В \Symfony\Component\Console\Application::doRunCommand - ловится исключение и:
1.1 порождает $event = new \Symfony\Component\Console\Event\ConsoleErrorEvent($exception)
1.2 вызывает $this->dispatcher->dispatch($event, ConsoleEvents::ERROR);
1.3 срабатывает \Symfony\Component\Console\EventListener\ErrorListener и логирует $exception с помощью
логгера с именем "console", который с помощью хендлера "fingers_crossed" записывает ошибку
2. В \Symfony\Component\Console\Application::run - ловится исключение и:
2.1 вызывается кэлбэк-функция $renderException($e)
2.2 вызывается \Symfony\Component\Console\Application::renderThrowable($exception, OutputInterface $output)
2.3 Symfony\Component\Console\Output\ConsoleOutput $output печатает ошибку форматируя ее с помощью \Symfony\Component\Console\Formatter\OutputFormatter
Кстати, о пункте 1 написано в официальной документации https://symfony.com/doc/current/console.html#logging-command-errors
use Symfony\Bundle\FrameworkBundle\Console\Application;
class JsonApplication extends Application
{
private LoggerInterface $logger;
public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function renderThrowable(\Throwable $e, OutputInterface $output): void
{
$this->logger->error('JsonApplication error', ['exception' => $e]);
}
}
$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$application = new JsonApplication($kernel);
$logger = new Logger('json_console_logger');
$handler = new StreamHandler(STDOUT, Logger::NOTICE);
$handler->setFormatter(new Monolog\Formatter\JsonFormatter());
$logger->pushHandler($handler);
$logger->pushProcessor(new My\Processor\AddInformationAboutExceptionProcessor());
$logger->pushProcessor(new My\Processor\EnvProcessor($application));
$application->setLogger($logger);
$application->run($input);Два сообщения об ошибке - избыточно, и т.к. мы верим фреймворку, логике его работы и стабильности, то второе логирование можно отключить или сделать опциональным:
class ApplicationWithoutRepeatableInformationAboutException extends Application
{
public function renderThrowable(\Throwable $e, OutputInterface $output): void
{
// http://yapro.ru/article/6438
}
}
$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$application = in_array('--show-the-exception-information-again', $_SERVER['argv']) ?
new Application($kernel) : new ApplicationWithoutRepeatableInformationAboutException($kernel);
$application->run($input);На практике исключение может быть выброшено еще до создания Symfony Application. Например \Symfony\Component\Console\Input\ArgvInput::parseArgument() может выбросить исключение, если в команде указать опцию без значения: --my-option-without-value
bin/console my:command --env=prod --my-option-without-value
[09-Aug-2021 06:51:20 UTC] PHP Fatal error: Uncaught Symfony\Component\Console\Exception\RuntimeException: No arguments expected, got "my:command". in /var/www/vendor/symfony/console/Input/ArgvInput.php:186
Stack trace:
#0 /var/www/vendor/symfony/console/Input/ArgvInput.php(80): Symfony\Component\Console\Input\ArgvInput->parseArgument('data-migration:...')
#1 /var/www/vendor/symfony/console/Input/Input.php(55): Symfony\Component\Console\Input\ArgvInput->parse()
#2 /var/www/vendor/symfony/console/Input/Input.php(41): Symfony\Component\Console\Input\Input->bind(Object(Symfony\Component\Console\Input\InputDefinition))
#3 /var/www/vendor/symfony/console/Input/ArgvInput.php(55): Symfony\Component\Console\Input\Input->__construct(Object(Symfony\Component\Console\Input\InputDefinition))
#4 /var/www/bin/console(25): Symfony\Component\Console\Input\ArgvInput->__construct(Array, Object(Symfony\Component\Console\Input\InputDefinition))
#5 {main}
thrown in /var/www/vendor/symfony/console/Input/ArgvInput.php on line 186А это значит, что для получения json-представления и в этом случае, нужно писать свой простой обработчик исключений и ошибок, удачи господа.
Источники: 1