mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-13 10:56:38 +00:00
tweaked error wrapping
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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...');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user