Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3399e7f

Browse filesBrowse files
committed
Add Console ExceptionListener
Handle non string-castable inputs Cleanup input for display Naming changes InputInterface doesnt have a toString() Logger must be private Remove useless doc blocks Tweak tests
1 parent 9896547 commit 3399e7f
Copy full SHA for 3399e7f

File tree

4 files changed

+84
-64
lines changed
Filter options

4 files changed

+84
-64
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/console.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/console.xml
+5-2Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
66

77
<services>
8-
<service id="console.exception_listener" class="Symfony\Component\Console\EventListener\ExceptionListener">
9-
<tag name="kernel.event_subscriber" />
8+
9+
<service id="console.exception_listener" class="Symfony\Component\Console\EventListener\ExceptionListener" public="false">
1010
<argument type="service" id="logger" on-invalid="null" />
11+
<tag name="kernel.event_subscriber" />
12+
<tag name="monolog.logger" channel="console" />
1113
</service>
14+
1215
</services>
1316
</container>

‎src/Symfony/Component/Console/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
3.3.0
55
-----
66

7+
* added `ExceptionListener`
78
* added `AddConsoleCommandPass` (originally in FrameworkBundle)
89

910
3.2.0

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/EventListener/ExceptionListener.php
+23-34Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,79 +12,68 @@
1212
namespace Symfony\Component\Console\EventListener;
1313

1414
use Psr\Log\LoggerInterface;
15+
use Symfony\Component\Console\Event\ConsoleEvent;
1516
use Symfony\Component\Console\ConsoleEvents;
1617
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
1718
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
1819
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1920

2021
/**
21-
* Console exception listener.
22-
*
23-
* Attempts to log exceptions or abnormal terminations of console commands.
24-
*
2522
* @author James Halsall <james.t.halsall@googlemail.com>
23+
* @author Robin Chalas <robin.chalas@gmail.com>
2624
*/
2725
class ExceptionListener implements EventSubscriberInterface
2826
{
29-
/**
30-
* @var LoggerInterface
31-
*/
32-
protected $logger;
33-
34-
/**
35-
* Constructor.
36-
*
37-
* @param LoggerInterface $logger A logger
38-
*/
27+
private $logger;
28+
3929
public function __construct(LoggerInterface $logger = null)
4030
{
4131
$this->logger = $logger;
4232
}
4333

44-
/**
45-
* Handles console command exception.
46-
*
47-
* @param ConsoleExceptionEvent $event Console event
48-
*/
49-
public function onKernelException(ConsoleExceptionEvent $event)
34+
public function onConsoleException(ConsoleExceptionEvent $event)
5035
{
5136
if (null === $this->logger) {
5237
return;
5338
}
5439

5540
$exception = $event->getException();
56-
$input = (string) $event->getInput();
5741

58-
$this->logger->error('Exception thrown while running command: "{command}". Message: "{message}"', array('exception' => $exception, 'command' => $input, 'message' => $exception->getMessage()));
42+
$this->logger->error('Exception thrown while running command "{command}". Message: "{message}"', array('exception' => $exception, 'command' => $this->getInputString($event), 'message' => $exception->getMessage()));
5943
}
6044

61-
/**
62-
* Handles termination of console command.
63-
*
64-
* @param ConsoleTerminateEvent $event Console event
65-
*/
66-
public function onKernelTerminate(ConsoleTerminateEvent $event)
45+
public function onConsoleTerminate(ConsoleTerminateEvent $event)
6746
{
6847
if (null === $this->logger) {
6948
return;
7049
}
7150

7251
$exitCode = $event->getExitCode();
7352

74-
if ($exitCode === 0) {
53+
if (0 === $exitCode) {
7554
return;
7655
}
7756

78-
$input = (string) $event->getInput();
79-
80-
$this->logger->error('Command "{command}" exited with status code "{code}"', array('command' => (string) $input, 'code' => $exitCode));
57+
$this->logger->error('Command "{command}" exited with code "{code}"', array('command' => $this->getInputString($event), 'code' => $exitCode));
8158
}
8259

8360
public static function getSubscribedEvents()
8461
{
8562
return array(
86-
ConsoleEvents::EXCEPTION => array('onKernelException', -128),
87-
ConsoleEvents::TERMINATE => array('onKernelTerminate', -128),
63+
ConsoleEvents::EXCEPTION => array('onConsoleException', -128),
64+
ConsoleEvents::TERMINATE => array('onConsoleTerminate', -128),
8865
);
8966
}
67+
68+
private static function getInputString(ConsoleEvent $event)
69+
{
70+
$commandName = $event->getCommand()->getName();
71+
$input = $event->getInput();
72+
73+
if (method_exists($input, '__toString')) {
74+
return str_replace(array("'$commandName'", "\"$commandName\""), $commandName, (string) $input);
75+
}
76+
77+
return $commandName;
78+
}
9079
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/EventListener/ExceptionListenerTest.php
+55-28Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,83 +16,110 @@
1616
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
1717
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
1818
use Symfony\Component\Console\EventListener\ExceptionListener;
19+
use Symfony\Component\Console\Input\ArgvInput;
1920
use Symfony\Component\Console\Input\ArrayInput;
20-
use Symfony\Component\Console\Tests\Output\TestOutput;
21+
use Symfony\Component\Console\Input\StringInput;
22+
use Symfony\Component\Console\Input\InputInterface;
23+
use Symfony\Component\Console\Output\OutputInterface;
2124

2225
class ExceptionListenerTest extends \PHPUnit_Framework_TestCase
2326
{
24-
public function testOnKernelException()
27+
public function testOnConsoleException()
2528
{
26-
$logger = $this->getLogger();
27-
$listener = new ExceptionListener($logger);
28-
2929
$exception = new \RuntimeException('An error occurred');
3030

31+
$logger = $this->getLogger();
3132
$logger
3233
->expects($this->once())
3334
->method('error')
34-
->with('Exception thrown while running command: "{command}". Message: "{message}"', array('exception' => $exception, 'command' => '\'test:run\' --foo=baz buzz', 'message' => 'An error occurred'))
35+
->with('Exception thrown while running command "{command}". Message: "{message}"', array('exception' => $exception, 'command' => 'test:run --foo=baz buzz', 'message' => 'An error occurred'))
3536
;
3637

37-
$input = array(
38-
'name' => 'test:run',
39-
'--foo' => 'baz',
40-
'bar' => 'buzz'
41-
);
42-
43-
$listener->onKernelException($this->getConsoleExceptionEvent($exception, $input, 1));
38+
$listener = new ExceptionListener($logger);
39+
$listener->onConsoleException($this->getConsoleExceptionEvent($exception, new ArgvInput(array('console.php', 'test:run', '--foo=baz', 'buzz')), 1));
4440
}
4541

46-
public function testOnKernelTerminateForNonZeroExitCodeWritesToLog()
42+
public function testOnConsoleTerminateForNonZeroExitCodeWritesToLog()
4743
{
4844
$logger = $this->getLogger();
49-
$listener = new ExceptionListener($logger);
50-
5145
$logger
5246
->expects($this->once())
5347
->method('error')
54-
->with('Command "{command}" exited with status code "{code}"', array('command' => '\'test:run\'', 'code' => 255))
48+
->with('Command "{command}" exited with code "{code}"', array('command' => 'test:run', 'code' => 255))
5549
;
5650

57-
$listener->onKernelTerminate($this->getConsoleTerminateEvent(array('name' => 'test:run'), 255));
51+
$listener = new ExceptionListener($logger);
52+
$listener->onConsoleTerminate($this->getConsoleTerminateEvent(new ArgvInput(array('console.php', 'test:run')), 255));
5853
}
5954

60-
public function testOnKernelTerminateForZeroExitCodeDoesNotWriteToLog()
55+
public function testOnConsoleTerminateForZeroExitCodeDoesNotWriteToLog()
6156
{
6257
$logger = $this->getLogger();
63-
$listener = new ExceptionListener($logger);
64-
6558
$logger
6659
->expects($this->never())
6760
->method('error')
6861
;
6962

70-
$listener->onKernelTerminate($this->getConsoleTerminateEvent(array('name' => 'test:run'), 0));
63+
$listener = new ExceptionListener($logger);
64+
$listener->onConsoleTerminate($this->getConsoleTerminateEvent(new ArgvInput(array('console.php', 'test:run')), 0));
7165
}
7266

7367
public function testGetSubscribedEvents()
7468
{
7569
$this->assertEquals(
7670
array(
77-
'console.exception' => array('onKernelException', -128),
78-
'console.terminate' => array('onKernelTerminate', -128),
71+
'console.exception' => array('onConsoleException', -128),
72+
'console.terminate' => array('onConsoleTerminate', -128),
7973
),
8074
ExceptionListener::getSubscribedEvents()
8175
);
8276
}
8377

78+
public function testAllKindsOfInputCanBeLogged()
79+
{
80+
$logger = $this->getLogger();
81+
$logger
82+
->expects($this->exactly(3))
83+
->method('error')
84+
->with('Command "{command}" exited with code "{code}"', array('command' => 'test:run --foo=bar', 'code' => 255))
85+
;
86+
87+
$listener = new ExceptionListener($logger);
88+
$listener->onConsoleTerminate($this->getConsoleTerminateEvent(new ArgvInput(array('console.php', 'test:run', '--foo=bar')), 255));
89+
$listener->onConsoleTerminate($this->getConsoleTerminateEvent(new ArrayInput(array('name' => 'test:run', '--foo' => 'bar')), 255));
90+
$listener->onConsoleTerminate($this->getConsoleTerminateEvent(new StringInput('test:run --foo=bar'), 255));
91+
}
92+
93+
public function testCommandNameIsDisplayedForNonStringableInput()
94+
{
95+
$logger = $this->getLogger();
96+
$logger
97+
->expects($this->once())
98+
->method('error')
99+
->with('Command "{command}" exited with code "{code}"', array('command' => 'test:run', 'code' => 255))
100+
;
101+
102+
$listener = new ExceptionListener($logger);
103+
$listener->onConsoleTerminate($this->getConsoleTerminateEvent($this->getMockBuilder(InputInterface::class)->getMock(), 255));
104+
}
105+
84106
private function getLogger()
85107
{
86108
return $this->getMockForAbstractClass(LoggerInterface::class);
87109
}
88110

89-
private function getConsoleExceptionEvent(\Exception $exception, $input, $exitCode)
111+
private function getConsoleExceptionEvent(\Exception $exception, InputInterface $input, $exitCode)
112+
{
113+
return new ConsoleExceptionEvent(new Command('test:run'), $input, $this->getOutput(), $exception, $exitCode);
114+
}
115+
116+
private function getConsoleTerminateEvent(InputInterface $input, $exitCode)
90117
{
91-
return new ConsoleExceptionEvent(new Command('test:run'), new ArrayInput($input), new TestOutput(), $exception, $exitCode);
118+
return new ConsoleTerminateEvent(new Command('test:run'), $input, $this->getOutput(), $exitCode);
92119
}
93120

94-
private function getConsoleTerminateEvent($input, $exitCode)
121+
private function getOutput()
95122
{
96-
return new ConsoleTerminateEvent(new Command('test:run'), new ArrayInput($input), new TestOutput(), $exitCode);
123+
return $this->getMockBuilder(OutputInterface::class)->getMock();
97124
}
98125
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.