merged branch fabpot/console-render-exception (PR #9055)
This PR was merged into the 2.2 branch. Discussion ---------- [Console] Fixed exception rendering | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #9045 | License | MIT | Doc PR | n/a When an exception message contains styles, the output is not the expected one. This PR addresses this issue. Commits -------c8d0342
[Console] fixed exception rendering when nested styles1f88a28
[Console] added some more information about OutputFormatter::replaceStyle()a47d663
[Console] fixed the formatter for single-char tagsc6c35b3
[Console] Escape exception message during the rendering of an exception
This commit is contained in:
commit
6f5de6315b
|
@ -808,29 +808,29 @@ class Application
|
|||
$title = sprintf(' [%s] ', get_class($e));
|
||||
$len = $strlen($title);
|
||||
$width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX;
|
||||
$formatter = $output->getFormatter();
|
||||
$lines = array();
|
||||
foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) {
|
||||
foreach (str_split($line, $width - 4) as $line) {
|
||||
$lines[] = sprintf(' %s ', $line);
|
||||
$len = max($strlen($line) + 4, $len);
|
||||
// pre-format lines to get the right string length
|
||||
$lineLength = $strlen(preg_replace('/\[[^m]*m/', '', $formatter->format($line))) + 4;
|
||||
$lines[] = array($line, $lineLength);
|
||||
|
||||
$len = max($lineLength, $len);
|
||||
}
|
||||
}
|
||||
|
||||
$messages = array(str_repeat(' ', $len), $title.str_repeat(' ', max(0, $len - $strlen($title))));
|
||||
|
||||
$messages = array('', '');
|
||||
$messages[] = $emptyLine = $formatter->format(sprintf('<error>%s</error>', str_repeat(' ', $len)));
|
||||
$messages[] = $formatter->format(sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - $strlen($title)))));
|
||||
foreach ($lines as $line) {
|
||||
$messages[] = $line.str_repeat(' ', $len - $strlen($line));
|
||||
$messages[] = $formatter->format(sprintf('<error> %s %s</error>', $line[0], str_repeat(' ', $len - $line[1])));
|
||||
}
|
||||
$messages[] = $emptyLine;
|
||||
$messages[] = '';
|
||||
$messages[] = '';
|
||||
|
||||
$messages[] = str_repeat(' ', $len);
|
||||
|
||||
$output->writeln("");
|
||||
$output->writeln("");
|
||||
foreach ($messages as $message) {
|
||||
$output->writeln('<error>'.$message.'</error>');
|
||||
}
|
||||
$output->writeln("");
|
||||
$output->writeln("");
|
||||
$output->writeln($messages, OutputInterface::OUTPUT_RAW);
|
||||
|
||||
if (OutputInterface::VERBOSITY_VERBOSE === $output->getVerbosity()) {
|
||||
$output->writeln('<comment>Exception trace:</comment>');
|
||||
|
|
|
@ -23,7 +23,7 @@ class OutputFormatter implements OutputFormatterInterface
|
|||
/**
|
||||
* The pattern to phrase the format.
|
||||
*/
|
||||
const FORMAT_PATTERN = '#(\\\\?)<(/?)([a-z][a-z0-9_=;-]+)?>((?: [^<\\\\]+ | (?!<(?:/?[a-z]|/>)). | .(?<=\\\\<) )*)#isx';
|
||||
const FORMAT_PATTERN = '#(\\\\?)<(/?)([a-z][a-z0-9_=;-]*)?>((?: [^<\\\\]+ | (?!<(?:/?[a-z]|/>)). | .(?<=\\\\<) )*)#isx';
|
||||
|
||||
private $decorated;
|
||||
private $styles = array();
|
||||
|
@ -163,6 +163,8 @@ class OutputFormatter implements OutputFormatterInterface
|
|||
/**
|
||||
* Replaces style of the output.
|
||||
*
|
||||
* All escaped tags and tags that reference unknown styles are kept as is.
|
||||
*
|
||||
* @param array $match
|
||||
*
|
||||
* @return string The replaced style
|
||||
|
|
|
@ -429,6 +429,9 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
|||
$tester->run(array('command' => 'foo3:bar'), array('decorated' => false));
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3.txt', $this->normalizeLineBreaks($tester->getDisplay()), '->renderException() renders a pretty exceptions with previous exceptions');
|
||||
|
||||
$tester->run(array('command' => 'foo3:bar'), array('decorated' => true));
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');
|
||||
|
||||
$application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
|
||||
$application->setAutoExit(false);
|
||||
$application->expects($this->any())
|
||||
|
|
|
@ -17,9 +17,13 @@ class Foo3Command extends Command
|
|||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
try {
|
||||
throw new \Exception("First exception");
|
||||
try {
|
||||
throw new \Exception("First exception <p>this is html</p>");
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception("Second exception <comment>comment</comment>", 0, $e);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception("Second exception", 0, $e);
|
||||
throw new \Exception("Third exception <fg=blue;bg=red>comment</>", 0, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,25 @@
|
|||
|
||||
|
||||
|
||||
[Exception]
|
||||
Second exception
|
||||
|
||||
|
||||
[Exception]
|
||||
Third exception comment
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[Exception]
|
||||
First exception
|
||||
|
||||
|
||||
[Exception]
|
||||
Second exception comment
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[Exception]
|
||||
First exception <p>this is html</p>
|
||||
|
||||
|
||||
|
||||
foo3:bar
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
|
||||
[37;41m [0m
|
||||
[37;41m [Exception] [0m
|
||||
[37;41m Third exception [0m[34;41mcomment[0m[37;41m [0m
|
||||
[37;41m [0m
|
||||
|
||||
|
||||
|
||||
|
||||
[37;41m [0m
|
||||
[37;41m [Exception] [0m
|
||||
[37;41m Second exception [0m[33mcomment[0m[37;41m [0m
|
||||
[37;41m [0m
|
||||
|
||||
|
||||
|
||||
|
||||
[37;41m [0m
|
||||
[37;41m [Exception] [0m
|
||||
[37;41m First exception [0m[37;41m<p>this is html[0m[37;41m</p> [0m
|
||||
[37;41m [0m
|
||||
|
||||
|
||||
[32mfoo3:bar[0m
|
||||
|
||||
|
|
@ -113,7 +113,10 @@ class FormatterStyleTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals($style, $formatter->getStyle('test'));
|
||||
$this->assertNotEquals($style, $formatter->getStyle('info'));
|
||||
|
||||
$this->assertEquals("\033[34;47msome custom msg\033[0m", $formatter->format('<test>some custom msg</test>'));
|
||||
$style = new OutputFormatterStyle('blue', 'white');
|
||||
$formatter->setStyle('b', $style);
|
||||
|
||||
$this->assertEquals("\033[34;47msome \033[0m\033[34;47mcustom\033[0m\033[34;47m msg\033[0m", $formatter->format('<test>some <b>custom</b> msg</test>'));
|
||||
}
|
||||
|
||||
public function testRedefineStyle()
|
||||
|
@ -137,7 +140,7 @@ class FormatterStyleTest extends \PHPUnit_Framework_TestCase
|
|||
public function testNonStyleTag()
|
||||
{
|
||||
$formatter = new OutputFormatter(true);
|
||||
$this->assertEquals("\033[32msome \033[0m\033[32m<tag> styled\033[0m", $formatter->format('<info>some <tag> styled</info>'));
|
||||
$this->assertEquals("\033[32msome \033[0m\033[32m<tag> styled \033[0m\033[32m<p>single-char tag\033[0m\033[32m</p>\033[0m", $formatter->format('<info>some <tag> styled <p>single-char tag</p></info>'));
|
||||
}
|
||||
|
||||
public function testNotDecoratedFormatter()
|
||||
|
|
Reference in New Issue