mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-17 21:07:18 +00:00
Deduplicate template error handling
This commit is contained in:
+21
-32
@@ -410,23 +410,8 @@ abstract class Template
|
|||||||
try {
|
try {
|
||||||
$this->ensureSecurityChecked();
|
$this->ensureSecurityChecked();
|
||||||
yield from $this->doDisplay($context, $blocks);
|
yield from $this->doDisplay($context, $blocks);
|
||||||
} catch (Error $e) {
|
|
||||||
if (!$e->getSourceContext()) {
|
|
||||||
$e->setSourceContext($this->getSourceContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is mostly useful for \Twig\Error\LoaderError exceptions
|
|
||||||
// see \Twig\Error\LoaderError
|
|
||||||
if (-1 === $e->getTemplateLine()) {
|
|
||||||
$e->guess();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw $e;
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$e = new RuntimeError(\sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getSourceContext(), $e);
|
$this->handleException($e);
|
||||||
$e->guess();
|
|
||||||
|
|
||||||
throw $e;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -457,23 +442,8 @@ abstract class Template
|
|||||||
try {
|
try {
|
||||||
$template->ensureSecurityChecked();
|
$template->ensureSecurityChecked();
|
||||||
yield from $template->$block($context, $blocks);
|
yield from $template->$block($context, $blocks);
|
||||||
} catch (Error $e) {
|
|
||||||
if (!$e->getSourceContext()) {
|
|
||||||
$e->setSourceContext($template->getSourceContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is mostly useful for \Twig\Error\LoaderError exceptions
|
|
||||||
// see \Twig\Error\LoaderError
|
|
||||||
if (-1 === $e->getTemplateLine()) {
|
|
||||||
$e->guess();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw $e;
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$e = new RuntimeError(\sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getSourceContext(), $e);
|
$template->handleException($e);
|
||||||
$e->guess();
|
|
||||||
|
|
||||||
throw $e;
|
|
||||||
}
|
}
|
||||||
} elseif ($parent = $this->getParent($context)) {
|
} elseif ($parent = $this->getParent($context)) {
|
||||||
yield from $parent->unwrap()->yieldBlock($name, $context, array_merge($this->blocks, $blocks), false, $templateContext ?? $this);
|
yield from $parent->unwrap()->yieldBlock($name, $context, array_merge($this->blocks, $blocks), false, $templateContext ?? $this);
|
||||||
@@ -541,4 +511,23 @@ abstract class Template
|
|||||||
* @return iterable<scalar|\Stringable|null>
|
* @return iterable<scalar|\Stringable|null>
|
||||||
*/
|
*/
|
||||||
abstract protected function doDisplay(array $context, array $blocks = []): iterable;
|
abstract protected function doDisplay(array $context, array $blocks = []): iterable;
|
||||||
|
|
||||||
|
private function handleException(\Throwable $error): never
|
||||||
|
{
|
||||||
|
if ($error instanceof Error) {
|
||||||
|
if (!$error->getSourceContext()) {
|
||||||
|
$error->setSourceContext($this->getSourceContext());
|
||||||
|
}
|
||||||
|
if (-1 === $error->getTemplateLine()) {
|
||||||
|
$error->guess();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw $error;
|
||||||
|
}
|
||||||
|
|
||||||
|
$error = new RuntimeError(\sprintf('An exception has been thrown during the rendering of a template ("%s").', $error->getMessage()), -1, $this->getSourceContext(), $error);
|
||||||
|
$error->guess();
|
||||||
|
|
||||||
|
throw $error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ use Twig\Node\Node;
|
|||||||
use Twig\Source;
|
use Twig\Source;
|
||||||
use Twig\Token;
|
use Twig\Token;
|
||||||
use Twig\TokenParser\AbstractTokenParser;
|
use Twig\TokenParser\AbstractTokenParser;
|
||||||
|
use Twig\TwigFunction;
|
||||||
|
|
||||||
class ErrorTest extends TestCase
|
class ErrorTest extends TestCase
|
||||||
{
|
{
|
||||||
@@ -47,6 +48,24 @@ class ErrorTest extends TestCase
|
|||||||
$this->assertStringContainsString('tests'.\DIRECTORY_SEPARATOR.'ErrorTest.php', $error->getMessage());
|
$this->assertStringContainsString('tests'.\DIRECTORY_SEPARATOR.'ErrorTest.php', $error->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTwigErrorIsEnrichedWithoutBeingWrapped(): void
|
||||||
|
{
|
||||||
|
$twig = new Environment(new ArrayLoader(['index' => "foo\n{{ fail() }}"]), ['debug' => true, 'cache' => false]);
|
||||||
|
$error = null;
|
||||||
|
$twig->addFunction(new TwigFunction('fail', static function () use (&$error): never {
|
||||||
|
throw $error = new RuntimeError('Runtime error.');
|
||||||
|
}));
|
||||||
|
|
||||||
|
try {
|
||||||
|
$twig->render('index');
|
||||||
|
$this->fail();
|
||||||
|
} catch (RuntimeError $e) {
|
||||||
|
$this->assertSame($error, $e);
|
||||||
|
$this->assertSame(2, $e->getTemplateLine());
|
||||||
|
$this->assertSame('index', $e->getSourceContext()->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function testTwigExceptionGuessWithMissingVarAndArrayLoader(): void
|
public function testTwigExceptionGuessWithMissingVarAndArrayLoader(): void
|
||||||
{
|
{
|
||||||
$loader = new ArrayLoader([
|
$loader = new ArrayLoader([
|
||||||
|
|||||||
Reference in New Issue
Block a user