tweaked error wrapping
authorFabien Potencier <fabien.potencier@gmail.com>
Tue, 12 Apr 2011 07:12:05 +0000 (09:12 +0200)
committerFabien Potencier <fabien.potencier@gmail.com>
Tue, 12 Apr 2011 07:32:38 +0000 (09:32 +0200)
CHANGELOG
lib/Twig/Error.php
lib/Twig/Error/Wrapped.php [deleted file]
lib/Twig/Template.php
test/Twig/Tests/ErrorTest.php [new file with mode: 0644]

index bccaf16..673cbe5 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,7 +4,7 @@ Flush your cache after upgrading.
 
 Changes:
 
- * wrapped all runtime exceptions (Twig_Error_Wrapped) to try to add the template name and the line when a problem occurs
+ * wrapped all runtime exceptions with Twig_Error_Runtime and added logic to guess the template name and line
  * moved display() method to Twig_Template (generated templates should now use doDisplay() instead)
 
 * 1.0.0 (2011-03-27)
index e85c587..c291307 100644 (file)
@@ -32,6 +32,10 @@ class Twig_Error extends Exception
      */
     public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null)
     {
+        if (-1 === $lineno || null === $filename) {
+            list($lineno, $filename) = $this->findTemplateInfo(null !== $previous ? $previous : $this);
+        }
+
         $this->lineno = $lineno;
         $this->filename = $filename;
         $this->rawMessage = $message;
@@ -119,4 +123,49 @@ class Twig_Error extends Exception
             $this->message .= sprintf(' at line %d', $this->lineno);
         }
     }
+
+    protected function findTemplateInfo(Exception $e)
+    {
+        if (!function_exists('token_get_all')) {
+            return array(-1, null);
+        }
+
+        $traces = $e->getTrace();
+        foreach ($traces as $i => $trace) {
+            if (!isset($trace['class']) || !isset($trace['line']) || 'Twig_Template' === $trace['class']) {
+                continue;
+            }
+
+            $r = new ReflectionClass($trace['class']);
+            if (!$r->implementsInterface('Twig_TemplateInterface')) {
+                continue;
+            }
+
+            $trace = $traces[$i - 1];
+
+            if (!file_exists($r->getFilename())) {
+                // probably an eval()'d code
+                return array(-1, null);
+            }
+
+            $tokens = token_get_all(file_get_contents($r->getFilename()));
+            $currentline = 0;
+            $templateline = -1;
+            $template = null;
+            while ($token = array_shift($tokens)) {
+                if (T_WHITESPACE === $token[0]) {
+                    $currentline += substr_count($token[1], "\n");
+                    if ($currentline >= $trace['line']) {
+                        return array($templateline, $template);
+                    }
+                } elseif (T_COMMENT === $token[0] && null === $template && preg_match('#/\* +(.+) +\*/#', $token[1], $match)) {
+                    $template = $match[1];
+                } elseif (T_COMMENT === $token[0] && preg_match('#line (\d+)#', $token[1], $match)) {
+                    $templateline = $match[1];
+                }
+            }
+        }
+
+        return array(-1, null);
+    }
 }
diff --git a/lib/Twig/Error/Wrapped.php b/lib/Twig/Error/Wrapped.php
deleted file mode 100644 (file)
index 54190fd..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-/*
- * This file is part of Twig.
- *
- * (c) 2011 Fabien Potencier
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-/**
- * Twig base exception.
- *
- * @package    twig
- * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
- */
-class Twig_Error_Wrapped extends Twig_Error_Runtime
-{
-    public function __construct(Exception $e)
-    {
-        if ($e instanceof Twig_Error && -1 !== $e->getTemplateLine() && null === $e->getTemplateFile()) {
-            parent::__construct($e->getMessage(), $e->getTemplateLine(), $e->getTemplateFile(), $e);
-        } else {
-            list($lineno, $filename) = $this->findTemplateInfo($e);
-
-            parent::__construct($e->getMessage(), $lineno, $filename, $e);
-        }
-    }
-
-    protected function findTemplateInfo(Exception $e)
-    {
-        if (!function_exists('token_get_all')) {
-            return array(-1, null);
-        }
-
-        $traces = $e->getTrace();
-        foreach ($traces as $i => $trace) {
-            if (!isset($trace['class']) || !isset($trace['line']) || 'Twig_Template' === $trace['class']) {
-                continue;
-            }
-
-            $r = new ReflectionClass($trace['class']);
-            if (!$r->implementsInterface('Twig_TemplateInterface')) {
-                continue;
-            }
-
-            $trace = $traces[$i - 1];
-
-            if (!file_exists($r->getFilename())) {
-                // probably an eval()'d code
-                return array(-1, null);
-            }
-
-            $tokens = token_get_all(file_get_contents($r->getFilename()));
-            $currentline = 0;
-            $templateline = -1;
-            $template = null;
-            while ($token = array_shift($tokens)) {
-                if (T_WHITESPACE === $token[0]) {
-                    $currentline += substr_count($token[1], "\n");
-                    if ($currentline >= $trace['line']) {
-                        return array($templateline, $template);
-                    }
-                } elseif (T_COMMENT === $token[0] && null === $template && preg_match('#/\* +(.+) +\*/#', $token[1], $match)) {
-                    $template = $match[1];
-                } elseif (T_COMMENT === $token[0] && preg_match('#line (\d+)#', $token[1], $match)) {
-                    $templateline = $match[1];
-                }
-            }
-        }
-
-        return array(-1, null);
-    }
-}
index 6a6ff3b..34556c1 100644 (file)
@@ -169,7 +169,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
         } catch (Twig_Error $e) {
             throw $e;
         } catch (Exception $e) {
-            throw new Twig_Error_Wrapped($e);
+            throw new Twig_Error_Runtime($e->getMessage(), -1, null, $e);
         }
     }
 
diff --git a/test/Twig/Tests/ErrorTest.php b/test/Twig/Tests/ErrorTest.php
new file mode 100644 (file)
index 0000000..7af3036
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+require_once dirname(__FILE__).'/TestCase.php';
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Twig_Tests_ErrorTest extends Twig_Tests_TestCase
+{
+    /*
+    public function testTwigExceptionAddsFileAndLineWhenMissing()
+    {
+        $loader = new Twig_Loader_Array(array('index' => "\n\n{{ foo.bar }}"));
+        $twig = new Twig_Environment($loader, array('strict_variables' => true, 'debug' => true, 'cache' => $this->getTempDir()));
+
+        $template = $twig->loadTemplate('index');
+
+        try {
+            $template->render(array());
+        } catch (Twig_Error_Runtime $e) {
+            $this->assertEquals(3, $e->getTemplateLine());
+            $this->assertEquals('index', $e->getTemplateFile());
+        }
+    }
+*/
+    public function testRenderWrapsExceptions()
+    {
+        $loader = new Twig_Loader_Array(array('index' => "\n\n{{ foo.bar }}"));
+        $twig = new Twig_Environment($loader, array('strict_variables' => true, 'debug' => true, 'cache' => $this->getTempDir()));
+
+        $template = $twig->loadTemplate('index');
+
+        try {
+            $template->render(array('foo' => new Twig_Tests_ErrorTest_Foo()));
+        } catch (Twig_Error_Runtime $e) {
+            $this->assertEquals('Runtime error... in "index" at line 3', $e->getMessage());
+            $this->assertEquals(3, $e->getTemplateLine());
+            $this->assertEquals('index', $e->getTemplateFile());
+        }
+    }
+}
+
+class Twig_Tests_ErrorTest_Foo
+{
+    public function bar()
+    {
+        throw new Exception('Runtime error...');
+    }
+}