Selaa lähdekoodia

[Console] added rendering previous exceptions

Martin Hason 14 vuotta sitten
vanhempi
commit
f41654fd60

+ 42 - 40
src/Symfony/Component/Console/Application.php

@@ -657,55 +657,57 @@ class Application
             return function_exists('mb_strlen') ? mb_strlen($string) : strlen($string);
         };
 
-        $title = sprintf('  [%s]  ', get_class($e));
-        $len = $strlen($title);
-        $lines = array();
-        foreach (explode("\n", $e->getMessage()) as $line) {
-            $lines[] = sprintf('  %s  ', $line);
-            $len = max($strlen($line) + 4, $len);
-        }
-
-        $messages = array(str_repeat(' ', $len), $title.str_repeat(' ', $len - $strlen($title)));
+        do {
+            $title = sprintf('  [%s]  ', get_class($e));
+            $len = $strlen($title);
+            $lines = array();
+            foreach (explode("\n", $e->getMessage()) as $line) {
+                $lines[] = sprintf('  %s  ', $line);
+                $len = max($strlen($line) + 4, $len);
+            }
 
-        foreach ($lines as $line) {
-            $messages[] = $line.str_repeat(' ', $len - $strlen($line));
-        }
+            $messages = array(str_repeat(' ', $len), $title.str_repeat(' ', $len - $strlen($title)));
 
-        $messages[] = str_repeat(' ', $len);
+            foreach ($lines as $line) {
+                $messages[] = $line.str_repeat(' ', $len - $strlen($line));
+            }
 
-        $output->writeln("\n");
-        foreach ($messages as $message) {
-            $output->writeln('<error>'.$message.'</error>');
-        }
-        $output->writeln("\n");
+            $messages[] = str_repeat(' ', $len);
 
-        if (null !== $this->runningCommand) {
-            $output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())));
             $output->writeln("\n");
-        }
-
-        if (Output::VERBOSITY_VERBOSE === $output->getVerbosity()) {
-            $output->writeln('</comment>Exception trace:</comment>');
-
-            // exception related properties
-            $trace = $e->getTrace();
-            array_unshift($trace, array(
-                'function' => '',
-                'file'     => $e->getFile() != null ? $e->getFile() : 'n/a',
-                'line'     => $e->getLine() != null ? $e->getLine() : 'n/a',
-                'args'     => array(),
-            ));
+            foreach ($messages as $message) {
+                $output->writeln('<error>'.$message.'</error>');
+            }
+            $output->writeln("\n");
 
-            for ($i = 0, $count = count($trace); $i < $count; $i++) {
-                $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
-                $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
-                $function = $trace[$i]['function'];
-                $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a';
-                $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a';
+            if (Output::VERBOSITY_VERBOSE === $output->getVerbosity()) {
+                $output->writeln('</comment>Exception trace:</comment>');
+
+                // exception related properties
+                $trace = $e->getTrace();
+                array_unshift($trace, array(
+                    'function' => '',
+                    'file'     => $e->getFile() != null ? $e->getFile() : 'n/a',
+                    'line'     => $e->getLine() != null ? $e->getLine() : 'n/a',
+                    'args'     => array(),
+                ));
+
+                for ($i = 0, $count = count($trace); $i < $count; $i++) {
+                    $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
+                    $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
+                    $function = $trace[$i]['function'];
+                    $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a';
+                    $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a';
+
+                    $output->writeln(sprintf(' %s%s%s() at <info>%s:%s</info>', $class, $type, $function, $file, $line));
+                }
 
-                $output->writeln(sprintf(' %s%s%s() at <info>%s:%s</info>', $class, $type, $function, $file, $line));
+                $output->writeln("\n");
             }
+        } while ($e = $e->getPrevious());
 
+        if (null !== $this->runningCommand) {
+            $output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())));
             $output->writeln("\n");
         }
     }

+ 7 - 0
tests/Symfony/Tests/Component/Console/ApplicationTest.php

@@ -26,6 +26,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
         require_once self::$fixturesPath.'/FooCommand.php';
         require_once self::$fixturesPath.'/Foo1Command.php';
         require_once self::$fixturesPath.'/Foo2Command.php';
+        require_once self::$fixturesPath.'/Foo3Command.php';
     }
 
     protected function normalize($text)
@@ -245,6 +246,12 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
 
         $tester->run(array('command' => 'list', '--foo' => true));
         $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception2.txt', $this->normalize($tester->getDisplay()), '->renderException() renders the command synopsis when an exception occurs in the context of a command');
+
+        $application->add(new \Foo3Command);
+        $tester = new ApplicationTester($application);
+        $tester->run(array('command' => 'foo3:bar'));
+        $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3.txt', $this->normalize($tester->getDisplay()), '->renderException() renders a pretty exceptions with previous exceptions');
+
     }
 
     public function testRun()

+ 25 - 0
tests/Symfony/Tests/Component/Console/Fixtures/Foo3Command.php

@@ -0,0 +1,25 @@
+<?php
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Foo3Command extends Command
+{
+    protected function configure()
+    {
+        $this
+            ->setName('foo3:bar')
+            ->setDescription('The foo3:bar command')
+        ;
+    }
+
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        try {
+            throw new \Exception("First exception");
+        } catch (\Exception $e) {
+            throw new \Exception("Second exception", 0, $e);
+        }
+    }
+}

+ 19 - 0
tests/Symfony/Tests/Component/Console/Fixtures/application_renderexception3.txt

@@ -0,0 +1,19 @@
+
+
+                    
+  [Exception]       
+  Second exception  
+                    
+
+
+
+
+                   
+  [Exception]      
+  First exception  
+                   
+
+
+foo3:bar [-h|--help] [-q|--quiet] [-v|--verbose] [-V|--version] [-a|--ansi] [-n|--no-interaction] command
+
+