Skip to content

Commit

Permalink
[Console] Allow to catch CommandNotFoundException
Browse files Browse the repository at this point in the history
  • Loading branch information
chalasr committed Mar 29, 2017
1 parent 195e464 commit b21ce85
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 5 deletions.
4 changes: 2 additions & 2 deletions src/Symfony/Component/Console/Application.php
Expand Up @@ -128,8 +128,8 @@ public function run(InputInterface $input = null, OutputInterface $output = null
$exception = new FatalThrowableError($e);
}

if (null !== $this->runningCommand && null !== $e && null !== $this->dispatcher) {
$event = new ConsoleErrorEvent($this->runningCommand, $input, $output, $e, $e->getCode());
if (null !== $e && null !== $this->dispatcher) {
$event = new ConsoleErrorEvent($input, $output, $e, $e->getCode(), $this->runningCommand);
$this->dispatcher->dispatch(ConsoleEvents::ERROR, $event);

$e = $event->getError();
Expand Down
2 changes: 2 additions & 0 deletions src/Symfony/Component/Console/CHANGELOG.md
Expand Up @@ -10,6 +10,8 @@ CHANGELOG
with value optional explicitly passed empty
* added console.error event to catch exceptions thrown by other listeners
* deprecated console.exception event in favor of console.error
* added ability to handle `CommandNotFoundException` through the
`console.error` event

3.2.0
------
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/Console/Event/ConsoleErrorEvent.php
Expand Up @@ -27,7 +27,7 @@ class ConsoleErrorEvent extends ConsoleExceptionEvent
private $error;
private $handled = false;

public function __construct(Command $command, InputInterface $input, OutputInterface $output, $error, $exitCode)
public function __construct(InputInterface $input, OutputInterface $output, $error, $exitCode, Command $command = null)
{
if (!$error instanceof \Throwable && !$error instanceof \Exception) {
throw new InvalidArgumentException(sprintf('The error passed to ConsoleErrorEvent must be an instance of \Throwable or \Exception, "%s" was passed instead.', is_object($error) ? get_class($error) : gettype($error)));
Expand Down
Expand Up @@ -27,7 +27,7 @@ class ConsoleExceptionEvent extends ConsoleEvent
private $exception;
private $exitCode;

public function __construct(Command $command, InputInterface $input, OutputInterface $output, \Exception $exception, $exitCode, $deprecation = true)
public function __construct(Command $command = null, InputInterface $input, OutputInterface $output, \Exception $exception, $exitCode, $deprecation = true)
{
if ($deprecation) {
@trigger_error(sprintf('The %s class is deprecated since version 3.3 and will be removed in 4.0. Use the ConsoleErrorEvent instead.', __CLASS__), E_USER_DEPRECATED);
Expand Down
20 changes: 20 additions & 0 deletions src/Symfony/Component/Console/Tests/ApplicationTest.php
Expand Up @@ -1051,6 +1051,26 @@ public function testRunAllowsErrorListenersToSilenceTheException()
$this->assertEquals(0, $tester->getStatusCode());
}

public function testConsoleErrorEventIsTriggeredOnCommandNotFound()
{
$dispatcher = new EventDispatcher();
$dispatcher->addListener('console.error', function (ConsoleErrorEvent $event) {
$this->assertNull($event->getCommand());
$this->assertInstanceOf(CommandNotFoundException::class, $event->getError());
$event->getOutput()->write('silenced command not found');
$event->markErrorAsHandled();
});

$application = new Application();
$application->setDispatcher($dispatcher);
$application->setAutoExit(false);

$tester = new ApplicationTester($application);
$tester->run(array('command' => 'unknown'));
$this->assertContains('silenced command not found', $tester->getDisplay());
$this->assertEquals(0, $tester->getStatusCode());
}

/**
* @group legacy
* @expectedDeprecation The "console.exception" event is deprecated since version 3.3 and will be removed in 4.0. Use the "console.error" event instead.
Expand Down
Expand Up @@ -111,7 +111,7 @@ private function getLogger()

private function getConsoleErrorEvent(\Exception $exception, InputInterface $input, $exitCode)
{
return new ConsoleErrorEvent(new Command('test:run'), $input, $this->getOutput(), $exception, $exitCode);
return new ConsoleErrorEvent($input, $this->getOutput(), $exception, $exitCode, new Command('test:run'));
}

private function getConsoleTerminateEvent(InputInterface $input, $exitCode)
Expand Down

0 comments on commit b21ce85

Please sign in to comment.