8000 bug #22322 [Console] Fix fatal error when logging console.error witho… · symfony/symfony@9c0067b · GitHub
[go: up one dir, main page]

Skip to content

Commit 9c0067b

Browse files
committed
bug #22322 [Console] Fix fatal error when logging console.error without command (chalasr)
This PR was merged into the 3.3-dev branch. Discussion ---------- [Console] Fix fatal error when logging console.error without command | Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #22449 | License | MIT | Doc PR | n/a Happens now that the console.error event is dispatched on command not found, I ran into using `server:run` on 3.3 without `web-server-bundle` enabled: > PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function getName() on null In this case, this first tries to cast the event input as string (less good than when the command name is available, there're extra quotes around the command name) and, if can't be casted, uses a generic message. Commits ------- 97129fc Fix fatal error when logging console.error without a command
2 parents a84f59e + 97129fc commit 9c0067b

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

src/Symfony/Component/Console/EventListener/ExceptionListener.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ public function onConsoleError(ConsoleErrorEvent $event)
3939

4040
$error = $event->getError();
4141

42-
$this->logger->error('Error thrown while running command "{command}". Message: "{message}"', array('error' => $error, 'command' => $this->getInputString($event), 'message' => $error->getMessage()));
42+
if (!$inputString = $this->getInputString($event)) {
43+
return $this->logger->error('An error occurred while using the console. Message: "{message}"', array('error' => $error, 'message' => $error->getMessage()));
44+
}
45+
46+
$this->logger->error('Error thrown while running command "{command}". Message: "{message}"', array('error' => $error, 'command' => $inputString, 'message' => $error->getMessage()));
4347
}
4448

4549
public function onConsoleTerminate(ConsoleTerminateEvent $event)
@@ -54,7 +58,11 @@ public function onConsoleTerminate(ConsoleTerminateEvent $event)
5458
return;
5559
}
5660

57-
$this->logger->error('Command "{command}" exited with code "{code}"', array('command' => $this->getInputString($event), 'code' => $exitCode));
61+
if (!$inputString = $this->getInputString($event)) {
62+
return $this->logger->error('The console exited with code "{code}"', array('code' => $exitCode));
63+
}
64+
65+
$this->logger->error('Command "{command}" exited with code "{code}"', array('command' => $inputString, 'code' => $exitCode));
5866
}
5967

6068
public static function getSubscribedEvents()
@@ -67,11 +75,15 @@ public static function getSubscribedEvents()
6775

6876
private static function getInputString(ConsoleEvent $event)
6977
{
70-
$commandName = $event->getCommand()->getName();
78+
$commandName = $event->getCommand() ? $event->getCommand()->getName() : null;
7179
$input = $event->getInput();
7280

7381
if (method_exists($input, '__toString')) {
74-
return str_replace(array("'$commandName'", "\"$commandName\""), $commandName, (string) $input);
82+
if ($commandName) {
83+
return str_replace(array("'$commandName'", "\"$commandName\""), $commandName, (string) $input);
84+
}
85+
86+
return (string) $input;
7587
}
7688

7789
return $commandName;

src/Symfony/Component/Console/Tests/EventListener/ExceptionListenerTest.php

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\Console\EventListener\ExceptionListener;
2020
use Symfony\Component\Console\Input\ArgvInput;
2121
use Symfony\Component\Console\Input\ArrayInput;
22+
use Symfony\Component\Console\Input\Input;
2223
use Symfony\Component\Console\Input\StringInput;
2324
use Symfony\Component\Console\Input\InputInterface;
2425
use Symfony\Component\Console\Output\OutputInterface;
@@ -37,7 +38,22 @@ public function testOnConsoleError()
3738
;
3839

3940
$listener = new ExceptionListener($logger);
40-
$listener->onConsoleError($this->getConsoleErrorEvent($exception, new ArgvInput(array('console.php', 'test:run', '--foo=baz', 'buzz')), 1));
41+
$listener->onConsoleError($this->getConsoleErrorEvent($exception, new ArgvInput(array('console.php', 'test:run', '--foo=baz', 'buzz')), 1, new Command('test:run')));
42+
}
43+
44+
public function testOnConsoleErrorWithNoCommandAndNoInputString()
45+
{
46+
$exception = new \RuntimeException('An error occurred');
47+
48+
$logger = $this->getLogger();
49+
$logger
50+
->expects($this->once())
51+
->method('error')
52+
->with('An error occurred while using the console. Message: "{message}"', array('error' => $exception, 'message' => 'An error occurred'))
53+
;
54+
55+
$listener = new ExceptionListener($logger);
56+
$listener->onConsoleError($this->getConsoleErrorEvent($exception, new NonStringInput(), 1));
4157
}
4258

4359
public function testOnConsoleTerminateForNonZeroExitCodeWritesToLog()
@@ -109,9 +125,9 @@ private function getLogger()
109125
return $this->getMockForAbstractClass(LoggerInterface::class);
110126
}
111127

112-
private function getConsoleErrorEvent(\Exception $exception, InputInterface $input, $exitCode)
128+
private function getConsoleErrorEvent(\Exception $exception, InputInterface $input, $exitCode, Command $command = null)
113129
{
114-
return new ConsoleErrorEvent($input, $this->getOutput(), $exception, $exitCode, new Command('test:run'));
130+
return new ConsoleErrorEvent($input, $this->getOutput(), $exception, $exitCode, $command);
115131
}
116132

117133
private function getConsoleTerminateEvent(InputInterface $input, $exitCode)
@@ -124,3 +140,22 @@ private function getOutput()
124140
return $this->getMockBuilder(OutputInterface::class)->getMock();
125141
}
126142
}
143+
144+
class NonStringInput extends Input
145+
{
146+
public function getFirstArgument()
147+
{
148+
}
149+
150+
public function hasParameterOption($values, $onlyParams = false)
151+
{
152+
}
153+
154+
public function getParameterOption($values, $default = false, $onlyParams = false)
155+
{
156+
}
157+
158+
public function parse()
159+
{
160+
}
161+
}

0 commit comments

Comments
 (0)
0