mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-31 04:27:00 +00:00
Deduplicate template error handling
This commit is contained in:
+21
-32
@@ -410,23 +410,8 @@ abstract class Template
|
||||
try {
|
||||
$this->ensureSecurityChecked();
|
||||
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) {
|
||||
$e = new RuntimeError(\sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getSourceContext(), $e);
|
||||
$e->guess();
|
||||
|
||||
throw $e;
|
||||
$this->handleException($e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,23 +442,8 @@ abstract class Template
|
||||
try {
|
||||
$template->ensureSecurityChecked();
|
||||
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) {
|
||||
$e = new RuntimeError(\sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getSourceContext(), $e);
|
||||
$e->guess();
|
||||
|
||||
throw $e;
|
||||
$template->handleException($e);
|
||||
}
|
||||
} elseif ($parent = $this->getParent($context)) {
|
||||
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>
|
||||
*/
|
||||
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\Token;
|
||||
use Twig\TokenParser\AbstractTokenParser;
|
||||
use Twig\TwigFunction;
|
||||
|
||||
class ErrorTest extends TestCase
|
||||
{
|
||||
@@ -47,6 +48,24 @@ class ErrorTest extends TestCase
|
||||
$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
|
||||
{
|
||||
$loader = new ArrayLoader([
|
||||
|
||||
Reference in New Issue
Block a user