8000 [Console] Fix dispatching throwables from ConsoleEvents::COMMAND · symfony/symfony@222eb31 · GitHub
[go: up one dir, main page]

Skip to content

Commit 222eb31

Browse files
[Console] Fix dispatching throwables from ConsoleEvents::COMMAND
1 parent 5742958 commit 222eb31

File tree

2 files changed

+75
-28
lines changed

2 files changed

+75
-28
lines changed

src/Symfony/Component/Console/Application.php

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,15 @@ public function run(InputInterface $input = null, OutputInterface $output = null
117117
$this->configureIO($input, $output);
118118

119119
try {
120+
$e = null;
120121
$exitCode = $this->doRun($input, $output);
121-
} catch (\Exception $e) {
122+
} catch (\Exception $x) {
123+
$e = $x;
124+
} catch (\Throwable $x) {
125+
$e = new FatalThrowableError($x);
126+
}
127+
128+
if (null !== $e) {
122129
if (!$this->catchExceptions) {
123130
throw $e;
124131
}
@@ -839,47 +846,43 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI
839846
}
840847

841848
if (null === $this->dispatcher) {
842-
try {
843-
return $command->run($input, $output);
844-
} catch (\Exception $e) {
845-
throw $e;
846-
} catch (\Throwable $e) {
847-
throw new FatalThrowableError($e);
848-
}
849+
return $command->run($input, $output);
849850
}
850851

851852
$event = new ConsoleCommandEvent($command, $input, $output);
852-
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
853+
$e = null;
853854

854-
if ($event->commandShouldRun()) {
855-
try {
856-
$e = null;
855+
try {
856+
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
857+
858+
if ($event->commandShouldRun()) {
857859
$exitCode = $command->run($input, $output);
858-
} catch (\Exception $x) {
859-
$e = $x;
860-
} catch (\Throwable $x) {
861-
$e = new FatalThrowableError($x);
860+
} else {
861+
$exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
862862
}
863-
if (null !== $e) {
864-
$event = new ConsoleExceptionEvent($command, $input, $output, $e, $e->getCode());
865-
$this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event);
866-
867-
if ($e !== $event->getException()) {
868-
$x = $e = $event->getException();
869-
}
863+
} catch (\Exception $x) {
864+
$e = $x;
865+
} catch (\Throwable $x) {
866+
$e = new FatalThrowableError($x);
867+
}
870868

871-
$event = new ConsoleTerminateEvent($command, $input, $output, $e->getCode());
872-
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
869+
if (null !== $e) {
870+
$event = new ConsoleExceptionEvent($command, $input, $output, $e, $e->getCode());
871+
$this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event);
873872

874-
throw $x;
873+
if ($e !== $event->getException()) {
874+
$x = $e = $event->getException();
875875
}
876-
} else {
877-
$exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
876+
$exitCode = $e->getCode();
878877
}
879878

880879
$event = new ConsoleTerminateEvent($command, $input, $output, $exitCode);
881880
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
882881

882+
if (null !== $e) {
883+
throw $x;
884+
}
885+
883886
return $event->getExitCode();
884887
}
885888

src/Symfony/Component/Console/Tests/ApplicationTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,26 @@ public function testRunDispatchesAllEventsWithException()
977977
$this->assertContains('before.foo.caught.after.', $tester->getDisplay());
978978
}
979979

980+
public function testRunDispatchesAllEventsWithExceptionInListener()
981+
{
982+
$dispatcher = $this->getDispatcher();
983+
$dispatcher->addListener('cons F438 ole.command', function () {
984+
throw new \RuntimeException('foo');
985+
});
986+
987+
$application = new Application();
988+
$application->setDispatcher($dispatcher);
989+
$application->setAutoExit(false);
990+
991+
$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
992+
$output->write('foo.');
993+
});
994+
995+
$tester = new ApplicationTester($application);
996+
$tester->run(array('command' => 'foo'));
997+
$this->assertContains('before.caught.after.', $tester->getDisplay());
998+
}
999+
9801000
public function testRunWithError()
9811001
{
9821002
if (method_exists($this, 'expectException')) {
@@ -1000,6 +1020,30 @@ public function testRunWithError()
10001020
$tester->run(array('command' => 'dym'));
10011021
}
10021022

1023+
/**
1024+
* @requires PHP 7
1025+
*/
1026+
public function testErrorIsRethrownIfNotHandledByConsoleErrorEvent()
1027+
{
1028+
$application = new Application();
1029+
$application->setAutoExit(false);
1030+
$application->setDispatcher(new EventDispatcher());
1031+
1032+
$application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) {
1033+
new \UnknownClass();
1034+
});
1035+
1036+
$tester = new ApplicationTester($application);
1037+
1038+
try {
1039+
$tester->run(array('command' => 'dym'));
1040+
$this->fail('->run() should rethrow PHP errors if not handled via ConsoleErrorEvent.');
1041+
} catch (\Throwable $e) {
1042+
$this->assertInstanceOf('Error', $e);
1043+
$this->assertSame($e->getMessage(), 'Class \'UnknownClass\' not found');
1044+
}
1045+
}
1046+
10031047
/**
10041048
* @expectedException \LogicException
10051049
* @expectedExceptionMessage caught

0 commit comments

Comments
 (0)
0