Skip to content

Commit

Permalink
feature #2009 Clarify exception message in Twig_Template::getAttribut…
Browse files Browse the repository at this point in the history
…e (chalasr)

This PR was merged into the 1.x branch.

Discussion
----------

Clarify exception message in Twig_Template::getAttribute

When a non existing property/method is called for an object, the exception message is:

>  Method "property()" for object "[class]" does not exist in [template]"

But in fact the `Twig_Template::getAttribute()` method check for (at least) 3 more methods (`isProperty()`, `getProperty()` and `__call__()`).

It could be more adapted and easier to be debugged if the message would be:

> Neither the property "property" nor one of the methods "property]()", "getProperty()"/"isPropertyt()" or "__call()" exist and have public access in class "[class]" in [template]

This message is mostly inspired from the one used in the PropertyAccess component.

BTW I think that it would be great to replace all the checks listed above by a `PropertyAccessor::isReadable([property])`.
I can work on a PR if it's not overkill.

Commits
-------

d455b52 Clarify exception message in Twig_Template::getAttribute
  • Loading branch information
fabpot committed Apr 1, 2016
2 parents f0a4fa6 + d455b52 commit 3d0afc0
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 4 deletions.
2 changes: 1 addition & 1 deletion ext/twig/twig.c
Expand Up @@ -1040,7 +1040,7 @@ PHP_FUNCTION(twig_template_get_attributes)
efree(item);
return;
}
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Method \"%s\" for object \"%s\" does not exist", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Neither the property \"%s\" nor one of the methods \"%s()\", \"get%s()\"/\"is%s()\" or \"__call()\" exist and have public access in class \"%s\"", item, item, item, item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
efree(item);
return;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Twig/Template.php
Expand Up @@ -581,7 +581,7 @@ protected function getAttribute($object, $item, array $arguments = array(), $typ
return;
}

throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object)), -1, $this->getTemplateName());
throw new Twig_Error_Runtime(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s"', $item, get_class($object)), -1, $this->getTemplateName());
}

if ($isDefinedTest) {
Expand Down
4 changes: 2 additions & 2 deletions test/Twig/Tests/TemplateTest.php
Expand Up @@ -68,8 +68,8 @@ public function getAttributeExceptions()
array('{{ empty_array.a }}', 'Key "a" does not exist as the array is empty in "%s" at line 1', false),
array('{{ array.a }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1', false),
array('{{ attribute(array, -10) }}', 'Key "-10" for array with keys "foo" does not exist in "%s" at line 1', false),
array('{{ array_access.a }}', 'Method "a" for object "Twig_TemplateArrayAccessObject" does not exist in "%s" at line 1', false),
array('{% from _self import foo %}{% macro foo(obj) %}{{ obj.missing_method() }}{% endmacro %}{{ foo(array_access) }}', 'Method "missing_method" for object "Twig_TemplateArrayAccessObject" does not exist in "%s" at line 1', false),
array('{{ array_access.a }}', 'Neither the property "a" nor one of the methods "a()", "geta()"/"isa()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1', false),
array('{% from _self import foo %}{% macro foo(obj) %}{{ obj.missing_method() }}{% endmacro %}{{ foo(array_access) }}', 'Neither the property "missing_method" nor one of the methods "missing_method()", "getmissing_method()"/"ismissing_method()" or "__call()" exist and have public access in class "Twig_TemplateArrayAccessObject" in "%s" at line 1', false),
array('{{ magic_exception.test }}', 'An exception has been thrown during the rendering of a template ("Hey! Don\'t try to isset me!") in "%s" at line 1.', false),
array('{{ object["a"] }}', 'Impossible to access a key "a" on an object of class "stdClass" that does not implement ArrayAccess interface in "%s" at line 1', false),
);
Expand Down

0 comments on commit 3d0afc0

Please sign in to comment.