From ad427be36ecaee640bf88924a55b19223ed5b0a4 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 12 Apr 2011 07:58:02 +0200 Subject: [PATCH] added a Twig_Error_Wrapped exception to try to add template name and line when a problem occurs at runtime --- CHANGELOG | 9 +++++ lib/Twig/Error/Wrapped.php | 75 ++++++++++++++++++++++++++++++++++++++++++++ lib/Twig/Template.php | 8 ++++- 3 files changed, 91 insertions(+), 1 deletions(-) create mode 100644 lib/Twig/Error/Wrapped.php diff --git a/CHANGELOG b/CHANGELOG index 783d9df..bccaf16 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,12 @@ +* 1.1.0 (????-??-??) + +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 + * moved display() method to Twig_Template (generated templates should now use doDisplay() instead) + * 1.0.0 (2011-03-27) Changes: diff --git a/lib/Twig/Error/Wrapped.php b/lib/Twig/Error/Wrapped.php new file mode 100644 index 0000000..c4556c3 --- /dev/null +++ b/lib/Twig/Error/Wrapped.php @@ -0,0 +1,75 @@ + + */ +class Twig_Error_Wrapped extends Twig_Error_Runtime +{ + public function __construct(Exception $e) + { + if ($e instanceof Twig_Error) { + 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); + } +} diff --git a/lib/Twig/Template.php b/lib/Twig/Template.php index 99f8dfb..b7bd325 100644 --- a/lib/Twig/Template.php +++ b/lib/Twig/Template.php @@ -164,7 +164,13 @@ abstract class Twig_Template implements Twig_TemplateInterface */ public function display(array $context, array $blocks = array()) { - $this->doDisplay($context, $blocks); + try { + $this->doDisplay($context, $blocks); + } catch (Twig_Error $e) { + throw $e; + } catch (Exception $e) { + throw new Twig_Error_Wrapped($e); + } } /** -- 1.7.2.5