In |filter(), |map(), and |reduce(), throw a RuntimeError instead of a TypeError

This commit is contained in:
Thijs van Dijk
2020-05-28 17:37:56 +02:00
committed by Fabien Potencier
parent 3daadc5175
commit 567b1e2a06
2 changed files with 83 additions and 0 deletions
+4
View File
@@ -1724,6 +1724,10 @@ function twig_array_map($array, $arrow)
function twig_array_reduce($array, $arrow, $initial = null)
{
if (!\is_array($array)) {
if (!$array instanceof \Traversable) {
throw new RuntimeError(sprintf('The "reduce" filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($array)));
}
$array = iterator_to_array($array);
}
+79
View File
@@ -161,6 +161,85 @@ EOHTML
}
}
public function testTwigArrayFilterThrowsRuntimeExceptions()
{
$loader = new ArrayLoader([
'filter-null.html' => <<<EOHTML
{# Argument 1 passed to IteratorIterator::__construct() must implement interface Traversable, null given: #}
{% for n in variable|filter(x => x > 3) %}
This list contains {{n}}.
{% endfor %}
EOHTML
]);
$twig = new Environment($loader, ['debug' => true, 'cache' => false]);
$template = $twig->load('filter-null.html');
$out = $template->render(['variable' => [1, 2, 3, 4]]);
$this->assertEquals('This list contains 4.', trim($out));
try {
$template->render(['variable' => null]);
$this->fail();
} catch (RuntimeError $e) {
$this->assertEquals(2, $e->getTemplateLine());
$this->assertEquals('filter-null.html', $e->getSourceContext()->getName());
}
}
public function testTwigArrayMapThrowsRuntimeExceptions()
{
$loader = new ArrayLoader([
'map-null.html' => <<<EOHTML
{# We expect a runtime error if `variable` is not traversable #}
{% for n in variable|map(x => x * 3) %}
{{- n -}}
{% endfor %}
EOHTML
]);
$twig = new Environment($loader, ['debug' => true, 'cache' => false]);
$template = $twig->load('map-null.html');
$out = $template->render(['variable' => [1, 2, 3, 4]]);
$this->assertEquals('36912', trim($out));
try {
$template->render(['variable' => null]);
$this->fail();
} catch (RuntimeError $e) {
$this->assertEquals(2, $e->getTemplateLine());
$this->assertEquals('map-null.html', $e->getSourceContext()->getName());
}
}
public function testTwigArrayReduceThrowsRuntimeExceptions()
{
$loader = new ArrayLoader([
'reduce-null.html' => <<<EOHTML
{# We expect a runtime error if `variable` is not traversable #}
{{ variable|reduce((carry, x) => carry + x) }}
EOHTML
]);
$twig = new Environment($loader, ['debug' => true, 'cache' => false]);
$template = $twig->load('reduce-null.html');
$out = $template->render(['variable' => [1, 2, 3, 4]]);
$this->assertEquals('10', trim($out));
try {
$template->render(['variable' => null]);
$this->fail();
} catch (RuntimeError $e) {
$this->assertEquals(2, $e->getTemplateLine());
$this->assertEquals('reduce-null.html', $e->getSourceContext()->getName());
}
}
public function getErroredTemplates()
{
return [