From 97129fc611ea5239d8df0e9d1d94694c1b18b2c7 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Thu, 6 Apr 2017 21:15:13 +0200 Subject: [PATCH] Fix fatal error when logging console.error without a command --- .../EventListener/ExceptionListener.php | 20 +++++++-- .../EventListener/ExceptionListenerTest.php | 41 +++++++++++++++++-- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Console/EventListener/ExceptionListener.php b/src/Symfony/Component/Console/EventListener/ExceptionListener.php index f7b23058fb55..94bbc22fac41 100644 --- a/src/Symfony/Component/Console/EventListener/ExceptionListener.php +++ b/src/Symfony/Component/Console/EventListener/ExceptionListener.php @@ -39,7 +39,11 @@ public function onConsoleError(ConsoleErrorEvent $event) $error = $event->getError(); - $this->logger->error('Error thrown while running command "{command}". Message: "{message}"', array('error' => $error, 'command' => $this->getInputString($event), 'message' => $error->getMessage())); + if (!$inputString = $this->getInputString($event)) { + return $this->logger->error('An error occurred while using the console. Message: "{message}"', array('error' => $error, 'message' => $error->getMessage())); + } + + $this->logger->error('Error thrown while running command "{command}". Message: "{message}"', array('error' => $error, 'command' => $inputString, 'message' => $error->getMessage())); } public function onConsoleTerminate(ConsoleTerminateEvent $event) @@ -54,7 +58,11 @@ public function onConsoleTerminate(ConsoleTerminateEvent $event) return; } - $this->logger->error('Command "{command}" exited with code "{code}"', array('command' => $this->getInputString($event), 'code' => $exitCode)); + if (!$inputString = $this->getInputString($event)) { + return $this->logger->error('The console exited with code "{code}"', array('code' => $exitCode)); + } + + $this->logger->error('Command "{command}" exited with code "{code}"', array('command' => $inputString, 'code' => $exitCode)); } public static function getSubscribedEvents() @@ -67,11 +75,15 @@ public static function getSubscribedEvents() private static function getInputString(ConsoleEvent $event) { - $commandName = $event->getCommand()->getName(); + $commandName = $event->getCommand() ? $event->getCommand()->getName() : null; $input = $event->getInput(); if (method_exists($input, '__toString')) { - return str_replace(array("'$commandName'", "\"$commandName\""), $commandName, (string) $input); + if ($commandName) { + return str_replace(array("'$commandName'", "\"$commandName\""), $commandName, (string) $input); + } + + return (string) $input; } return $commandName; diff --git a/src/Symfony/Component/Console/Tests/EventListener/ExceptionListenerTest.php b/src/Symfony/Component/Console/Tests/EventListener/ExceptionListenerTest.php index a57235a867f5..295f75c06764 100644 --- a/src/Symfony/Component/Console/Tests/EventListener/ExceptionListenerTest.php +++ b/src/Symfony/Component/Console/Tests/EventListener/ExceptionListenerTest.php @@ -19,6 +19,7 @@ use Symfony\Component\Console\EventListener\ExceptionListener; use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Input\Input; use Symfony\Component\Console\Input\StringInput; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -37,7 +38,22 @@ public function testOnConsoleError() ; $listener = new ExceptionListener($logger); - $listener->onConsoleError($this->getConsoleErrorEvent($exception, new ArgvInput(array('console.php', 'test:run', '--foo=baz', 'buzz')), 1)); + $listener->onConsoleError($this->getConsoleErrorEvent($exception, new ArgvInput(array('console.php', 'test:run', '--foo=baz', 'buzz')), 1, new Command('test:run'))); + } + + public function testOnConsoleErrorWithNoCommandAndNoInputString() + { + $exception = new \RuntimeException('An error occurred'); + + $logger = $this->getLogger(); + $logger + ->expects($this->once()) + ->method('error') + ->with('An error occurred while using the console. Message: "{message}"', array('error' => $exception, 'message' => 'An error occurred')) + ; + + $listener = new ExceptionListener($logger); + $listener->onConsoleError($this->getConsoleErrorEvent($exception, new NonStringInput(), 1)); } public function testOnConsoleTerminateForNonZeroExitCodeWritesToLog() @@ -109,9 +125,9 @@ private function getLogger() return $this->getMockForAbstractClass(LoggerInterface::class); } - private function getConsoleErrorEvent(\Exception $exception, InputInterface $input, $exitCode) + private function getConsoleErrorEvent(\Exception $exception, InputInterface $input, $exitCode, Command $command = null) { - return new ConsoleErrorEvent($input, $this->getOutput(), $exception, $exitCode, new Command('test:run')); + return new ConsoleErrorEvent($input, $this->getOutput(), $exception, $exitCode, $command); } private function getConsoleTerminateEvent(InputInterface $input, $exitCode) @@ -124,3 +140,22 @@ private function getOutput() return $this->getMockBuilder(OutputInterface::class)->getMock(); } } + +class NonStringInput extends Input +{ + public function getFirstArgument() + { + } + + public function hasParameterOption($values, $onlyParams = false) + { + } + + public function getParameterOption($values, $default = false, $onlyParams = false) + { + } + + public function parse() + { + } +}