8000 [Console] The application also catch `\Throwable` exceptions · symfony/symfony@1baeb3d · GitHub
[go: up one dir, main page]

Skip to content

Commit 1baeb3d

Browse files
committed
[Console] The application also catch \Throwable exceptions
1 parent a2f75a2 commit 1baeb3d

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

src/Symfony/Component/Console/Application.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class Application implements ResetInterface
7979
private string $version;
8080
private ?CommandLoaderInterface $commandLoader = null;
8181
private bool $catchExceptions = true;
82+
private bool $catchErrors = false;
8283
private bool $autoExit = true;
8384
private InputDefinition $definition;
8485
private HelperSet $helperSet;
@@ -172,8 +173,11 @@ public function run(InputInterface $input = null, OutputInterface $output = null
172173

173174
try {
174175
$exitCode = $this->doRun($input, $output);
175-
} catch (\Exception $e) {
176-
if (!$this->catchExceptions) {
176+
} catch (\Throwable $e) {
177+
if ($e instanceof \Exception && !$this->catchExceptions) {
178+
throw $e;
179+
}
180+
if (!$e instanceof \Exception && !$this->catchErrors) {
177181
throw $e;
178182
}
179183

@@ -427,6 +431,14 @@ public function setCatchExceptions(bool $boolean)
427431
$this->catchExceptions = $boolean;
428432
}
429433

434+
/**
435+
* Sets whether to catch errors or not during commands execution.
436+
*/
437+
public function setCatchErrors(bool $catchErrors = true): void
438+
{
439+
$this->catchErrors = $catchErrors;
440+
}
441+
430442
/**
431443
* Gets whether to automatically exit after a command execution or not.
432444
*/

src/Symfony/Component/Console/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Add `SignalMap` to map signal value to its name
88
* Multi-line text in vertical tables is aligned properly
9+
* The application can also catch errors with `Application::setCatchErrors(true)`
910

1011
6.3
1112
---

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

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,10 +771,15 @@ public function testFindAmbiguousCommandsIfAllAlternativesAreHidden()
771771
$this->assertInstanceOf(\FooCommand::class, $application->find('foo:'));
772772
}
773773

774-
public function testSetCatchExceptions()
774+
/**
775+
* @testWith [true]
776+
* [false]
777+
*/
778+
public function testSetCatchExceptions(bool $catchErrors)
775779
{
776780
$application = new Application();
777781
$application->setAutoExit(false);
782+
$application->setCatchErrors($catchErrors);
778783
putenv('COLUMNS=120');
779784
$tester = new ApplicationTester($application);
780785

@@ -798,6 +803,33 @@ public function testSetCatchExceptions()
798803
}
799804
}
800805

806+
/**
807+
* @testWith [true]
808+
* [false]
809+
*/
810+
public function testSetCatchErrors(bool $catchExceptions)
811+
{
812+
$application = new Application();
813+
$application->setAutoExit(false);
814+
$application->setCatchExceptions($catchExceptions);
815+
$application->add((new Command('boom'))->setCode(fn () => throw new \Error('This is an error.')));
816+
817+
putenv('COLUMNS=120');
818+
$tester = new ApplicationTester($application);
819+
820+
try {
821+
$tester->run(['command' => 'boom']);
822+
$this->fail('The exception is not catched.');
823+
} catch (\Throwable $e) {
824+
$this->assertInstanceOf(\Error::class, $e);
825+
$this->assertSame('This is an error.', $e->getMessage());
826+
}
827+
828+
$application->setCatchErrors(true);
829+
$tester->run(['command' => 'boom']);
830+
$this->assertStringContainsString(' This is an error.', $tester->getDisplay(true));
831+
}
832+
801833
public function testAutoExitSetting()
802834
{
803835
$application = new Application();

0 commit comments

Comments
 (0)
0