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 55067cf

Browse filesBrowse files
committed
Added a console.ERROR event
1 parent 7bc268e commit 55067cf
Copy full SHA for 55067cf

File tree

Expand file treeCollapse file tree

8 files changed

+273
-43
lines changed
Filter options
Expand file treeCollapse file tree

8 files changed

+273
-43
lines changed

‎src/Symfony/Component/Console/Application.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Application.php
+31-6Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Symfony\Component\Console\Helper\Helper;
3434
use Symfony\Component\Console\Helper\FormatterHelper;
3535
use Symfony\Component\Console\Event\ConsoleCommandEvent;
36+
use Symfony\Component\Console\Event\ConsoleErrorEvent;
3637
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
3738
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
3839
use Symfony\Component\Console\Exception\CommandNotFoundException;
@@ -118,16 +119,40 @@ public function run(InputInterface $input = null, OutputInterface $output = null
118119
$this->configureIO($input, $output);
119120

120121
try {
122+
$e = null;
121123
$exitCode = $this->doRun($input, $output);
122124
} catch (\Exception $e) {
125+
$exception = $e;
126+
} catch (\Throwable $e) {
127+
$exception = new FatalThrowableError($e);
128+
}
129+
130+
if (null !== $e && null !== $this->dispatcher) {
131+
$event = new ConsoleErrorEvent($this->runningCommand, $input, $output, $e, $e->getCode());
132+
$this->dispatcher->dispatch(ConsoleEvents::ERROR, $event);
133+
134+
$e = $event->getError();
135+
136+
if ($event->isErrorHandled()) {
137+
$e = null;
138+
$exitCode = 0;
139+
} else {
140+
$exitCode = $e->getCode();
141+
}
142+
143+
$event = new ConsoleTerminateEvent($this->runningCommand, $input, $output, $exitCode);
144+
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
145+
}
146+
147+
if (null !== $e) {
123148
if (!$this->catchExceptions) {
124149
throw $e;
125150
}
126151

127152
if ($output instanceof ConsoleOutputInterface) {
128-
$this->renderException($e, $output->getErrorOutput());
153+
$this->renderException($exception, $output->getErrorOutput());
129154
} else {
130-
$this->renderException($e, $output);
155+
$this->renderException($exception, $output);
131156
}
132157

133158
$exitCode = $e->getCode();
@@ -863,17 +888,17 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI
863888
} catch (\Throwable $x) {
864889
$e = new FatalThrowableError($x);
865890
}
891+
866892
if (null !== $e) {
867-
$event = new ConsoleExceptionEvent($command, $input, $output, $e, $e->getCode());
893+
$event = new ConsoleExceptionEvent($command, $input, $output, $e, $e->getCode(), false);
868894
$this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event);
869895

870896
if ($e !== $event->getException()) {
897+
@trigger_error('The "console.exception" event is deprecated since version 3.3 and will be removed in 4.0. Use the "console.error" event instead.', E_USER_DEPRECATED);
898+
871899
$x = $e = $event->getException();
872900
}
873901

874-
$event = new ConsoleTerminateEvent($command, $input, $output, $e->getCode());
875-
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
876-
877902
throw $x;
878903
}
879904
} else {

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/CHANGELOG.md
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ CHANGELOG
1414

1515
* added truncate method to FormatterHelper
1616
* added setColumnWidth(s) method to Table
17+
* added console.error event to catch exceptions thrown by other
18+
listeners
19+
* deprecated console.exception event in favor of console.error
1720

1821
2.8.3
1922
-----

‎src/Symfony/Component/Console/ConsoleEvents.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/ConsoleEvents.php
+17-1Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ final class ConsoleEvents
4040
const TERMINATE = 'console.terminate';
4141

4242
/**
43-
* The EXCEPTION event occurs when an uncaught exception appears.
43+
* The EXCEPTION event occurs when an uncaught exception appears
44+
* while executing Command#run().
4445
*
4546
* This event allows you to deal with the exception or
4647
* to modify the thrown exception.
@@ -50,4 +51,19 @@ final class ConsoleEvents
5051
* @var string
5152
*/
5253
const EXCEPTION = 'console.exception';
54+
55+
/**
56+
* The ERROR event occurs when an uncaught exception appears or
57+
* a throwable error.
58+
*
59+
* This event allows you to deal with the exception/error or
60+
* to modify the thrown exception. The event listener method receives
61+
* a Symfony\Component\Console\Event\ConsoleExceptionEvent
62+
* instance.
63+
*
64+
* @Event
65+
*
66+
* @var string
67+
*/
68+
const ERROR = 'console.error';
5369
}
+108Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Console\Event;
13+
14+
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Exception\InvalidArgumentException;
16+
use Symfony\Component\Console\Input\InputInterface;
17+
use Symfony\Component\Console\Output\OutputInterface;
18+
use Symfony\Component\Debug\Exception\FatalThrowableError;
19+
20+
/**
21+
* Allows to handle throwables thrown while running a command.
22+
*
23+
* @author Wouter de Jong <wouter@wouterj.nl>
24+
*/
25+
class ConsoleErrorEvent extends ConsoleExceptionEvent
26+
{
27+
private $error;
28+
private $handled = false;
29+
30+
public function __construct(Command $command, InputInterface $input, OutputInterface $output, $error, $exitCode)
31+
{
32+
if (!$error instanceof \Throwable && !$error instanceof \Exception) {
33+
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)));
34+
}
35+
36+
$exception = $error;
37+
if (!$error instanceof \Exception) {
38+
$exception = new FatalThrowableError($error);
39+
}
40+
parent::__construct($command, $input, $output, $exception, $exitCode, false);
41+
42+
$this->error = $error;
43+
}
44+
45+
/**
46+
* Returns the thrown error/exception.
47+
*
48+
* @return \Throwable
49+
*/
50+
public function getError()
51+
{
52+
return $this->error;
53+
}
54+
55+
/**
56+
* Replaces the thrown error/exception.
57+
*
58+
* @param \Throwable|null $error
59+
*/
60+
public function setError(\Throwable $error)
61+
{
62+
$this->error = $error;
63+
}
64+
65+
/**
66+
* Marks the error/exception as handled.
67+
*
68+
* If it is not marked as handled, the error/exception will be displayed in
69+
* the command output.
70+
*/
71+
public function markErrorAsHandled()
72+
{
73+
$this->handled = true;
74+
}
75+
76+
/**
77+
* Whether the error/exception is handled by a listener or not.
78+
*
79+
* If it is not yet handled, the error/exception will be displayed in the
80+
* command output.
81+
*
82+
* @return bool
83+
*/
84+
public function isErrorHandled()
85+
{
86+
return $this->handled;
87+
}
88+
89+
/**
90+
* @deprecated Since version 3.3, to be removed in 4.0. Use getError() instead
91+
*/
92+
public function getException()
93+
{
94+
@trigger_error('The ConsoleExceptionEvent::'.__METHOD__.'() method is deprecated since version 3.3 and will be removed in 4.0. Use ConsoleErrorEvent::getError() instead.', E_USER_DEPRECATED);
95+
96+
return parent::getException();
97+
}
98+
99+
/**
100+
* @deprecated Since version 3.3, to be removed in 4.0. Use setError() instead
101+
*/
102+
public function setException(\Exception $exception)
103+
{
104+
@trigger_error('The ConsoleExceptionEvent::'.__METHOD__.'() method is deprecated since version 3.3 and will be removed in 4.0. Use ConsoleErrorEvent::setError() instead.', E_USER_DEPRECATED);
105+
106+
parent::setException($exception);
107+
}
108+
}

‎src/Symfony/Component/Console/Event/ConsoleEvent.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Event/ConsoleEvent.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class ConsoleEvent extends Event
2828
private $input;
2929
private $output;
3030

31-
public function __construct(Command $command, InputInterface $input, OutputInterface $output)
31+
public function __construct(Command $command = null, InputInterface $input, OutputInterface $output)
3232
{
3333
$this->command = $command;
3434
$this->input = $input;
@@ -38,7 +38,7 @@ public function __construct(Command $command, InputInterface $input, OutputInter
3838
/**
3939
* Gets the command that is executed.
4040
*
41-
* @return Command A Command instance
41+
* @return Command|null A Command instance
4242
*/
4343
public function getCommand()
4444
{

‎src/Symfony/Component/Console/Event/ConsoleExceptionEvent.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Event/ConsoleExceptionEvent.php
+9-2Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,24 @@
1919
* Allows to handle exception thrown in a command.
2020
*
2121
* @author Fabien Potencier <fabien@symfony.com>
22+
*
23+
* @deprecated ConsoleExceptionEvent is deprecated since version 3.2 and will be removed in 4.0. Use ConsoleErrorEvent instead.
2224
*/
2325
class ConsoleExceptionEvent extends ConsoleEvent
2426
{
2527
private $exception;
2628
private $exitCode;
29+
private $handled = false;
2730

28-
public function __construct(Command $command, InputInterface $input, OutputInterface $output, \Exception $exception, $exitCode)
31+
public function __construct(Command $command, InputInterface $input, OutputInterface $output, \Exception $exception, $exitCode, $deprecation = true)
2932
{
33+
if ($deprecation) {
34+
@trigger_error('The '.__CLASS__.' class is deprecated since version 3.3 and will be removed in 4.0. Use the ConsoleErrorEvent instead.', E_USER_DEPRECATED);
35+
}
36+
3037
parent::__construct($command, $input, $output);
3138

32-
$this->setException($exception);
39+
$this->exception = $exception;
3340
$this->exitCode = (int) $exitCode;
3441
}
3542

‎src/Symfony/Component/Console/Event/ConsoleTerminateEvent.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Event/ConsoleTerminateEvent.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class ConsoleTerminateEvent extends ConsoleEvent
2929
*/
3030
private $exitCode;
3131

32-
public function __construct(Command $command, InputInterface $input, OutputInterface $output, $exitCode)
32+
public function __construct(Command $command = null, InputInterface $input, OutputInterface $output, $exitCode)
3333
{
3434
parent::__construct($command, $input, $output);
3535

0 commit comments

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