Skip to content

[OptionsResolver] Exception doesn't report the actual type used #11021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

cleentfaar
Copy link

Q A
Bug fix? no
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #11020
License MIT
Doc PR -

Note to moderator: Stopwatch tests are failing randomly here; not related to this PR!
For more info, see #10454

UPDATE:

  • moved creation of printable value and type to separate methods for cleanliness
  • improved printable value by making a difference between an empty string and NULL.
  • restricted wrapping in quotes to only string values; further differentiating with other types.
  • when printable type is an object, it's classname get's returned instead of just 'object'

UPDATE 2:

  • applied feedback

UPDATE 3:

  • applied more feedback
  • squashed commits

$option,
$printableValue,
implode('", "', $allowedTypes)
implode('", "', $allowedTypes),
gettype($value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work nice with objects, its better to use something like is_object($value) ? get_class($value) : ettype($value) so you get the class-name instead of object ;)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixed

@cleentfaar cleentfaar changed the title [OptionsResolver] Exception doesn't report actual type used [OptionsResolver] Exception doesn't report the actual type used May 31, 2014
@@ -253,7 +259,7 @@ private function validateOptionsExistence(array $options)
ksort($diff);

throw new InvalidOptionsException(sprintf(
(count($diff) > 1 ? 'The options "%s" do not exist.' : 'The option "%s" does not exist.').' Known options are: "%s"',
(count($diff) > 1 ? 'The options "%s" do not exist.' : 'The option "%s" does not exist.') . ' Known options are: "%s"',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be reverted, Symfony CS doesn't use spaces around concatenating.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, reverted.

As a side note, I couldn't find a convention about concatenation in the CS nor in the conventions.

Could it get added to (one of) those pages?

@fabpot
Copy link
Member

fabpot commented Jun 16, 2014

@cleentfaar Can you have a look at the comments and update this PR accordingly?

@fabpot
Copy link
Member

fabpot commented Jun 16, 2014

@Tobion The only other option would be to abstract this into a component, but I find it quite overkill (I think @webmozart proposed to do that at some point as well.)

@Tobion
Copy link
Contributor

Tobion commented Jun 16, 2014

@fabpot It could be worth considering we need this type of logic everywhere. And it's not implemented consistently yet.

@cleentfaar
Copy link
Author

@fabpot Sorry, haven't had the time to get back on this PR lately.

Thanks for the feedback guys, I'm fixing it right now!

@cleentfaar
Copy link
Author

Applied some of your feedback guys, could you respond to the replies I made to the remaining notes? I will then it get fixed properly and ready to merge. All fixed!

@webmozart Did you manage to get a component ready for this like @fabpot mentioned?

If not I'm happy to get one set-up. Perhaps naming it something like Representation, Decoration, or Portrayal.

Not sure how I would make the createPrintableValue available though, seeing it's used in such exceptional cases, I suppose it would either need to be constructed in every piece of code it's used in, or making it static and thus callable in a single statement. Nice... but static stuff is something I always try to stay away from when I can. Let me know what you guys think of these suggestions.

Thanks!

@cleentfaar
Copy link
Author

@fabpot @webmozart Any feedback on my last comment?

@fabpot
Copy link
Member

fabpot commented Jul 15, 2014

If you are talking about creating a new component, that's not required for this PR and it should be discussed before writing code. So, this PR is fine by me as it is now.

@@ -294,13 +300,14 @@ private function validateOptionsCompleteness(array $options)
private function validateOptionValues(array $options)
{
foreach ($this->allowedValues as $option => $allowedValues) {
if (isset($options[$option])) {
if (array_key_exists($option, $options)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it intended to change the way null values are handled ?

@fabpot
Copy link
Member

fabpot commented Jul 23, 2014

@cleentfaar Any news?

@cleentfaar
Copy link
Author

@fabpot Sorry been away from this branch for a while.

Thanks for the feedback guys, I've applied your comments and squashed everything down so it's ready for merging imo. Let me know if there's something left though.

P.S.
I still kind of liked the idea of having this functionality in my private projects, but imo it should not be coupled to the OptionsResolver like this. So I created a small library to do exactly what the createPrintableValue does, without the tight coupling and having it's own testcase.
I've called it the Humanizer and you can find it here: https://github.com/cleentfaar/humanizer. If interested, I'd be happy to make a PR for the places where Symfony can use it (the OptionsResolver component being the first I can think of).

@Tobion
Copy link
Contributor

Tobion commented Jul 27, 2014

The components should not have such a dependency, which is why this code is duplicated everywhere. Also please rename the methods according to #10687: formatTypeOf and formatValue.
I guess you can just copy the methods with implementation from there.

@cleentfaar
Copy link
Author

@Tobion I've updated the code again, replacing my own formatters with those of #10687 for sake of consistency.

I can't really agree though on the (potentially) prettifying of \DateTime instances for the OptionsResolver here; it cannot be controlled by the user and so we would end up simply having to force it to always be prettified, or never... I'm not sure that's something we should do?

@fabpot
Copy link
Member

fabpot commented Aug 5, 2014

ping @webmozart

@cleentfaar
Copy link
Author

BTW, the test failure is not related to this PR

*
* @return string
*/
protected function formatTypeOf($value)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all these helper methods should be private

@fabpot
Copy link
Member

fabpot commented Sep 23, 2014

@cleentfaar Will you have time to update this PR according to @stof comments?

@stof
Copy link
Member

stof commented Sep 25, 2014

this need to be rebased to fix conflicts with the huge refactoring done in #11716

@cleentfaar cleentfaar force-pushed the issue-11020-exception-doesnt-report-actual-type-used branch from 2698bb3 to e4bff68 Compare October 6, 2014 07:03
@cleentfaar
Copy link
Author

@stof Will fix this tonight, thanks!

@cleentfaar cleentfaar force-pushed the issue-11020-exception-doesnt-report-actual-type-used branch from fba38bb to 98c4acc Compare October 10, 2014 06:25
…olver

further improved message of the exception
@cleentfaar cleentfaar force-pushed the issue-11020-exception-doesnt-report-actual-type-used branch from 88d2d61 to 0de9a59 Compare October 10, 2014 07:05
@cleentfaar
Copy link
Author

@stof Could you have a look again (rebased now)?

I've left out the parts where you could pass the format as an argument, as the user could not never control these arguments, the methods are only used during exception. Hope this is ok.

@@ -228,7 +247,7 @@ public static function validateTypes(array $options, array $acceptedTypes)
continue;
}

$value = $options[$option];
$value = $options[$option];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be reverted.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cheers

$printableValue,
implode('", "', $optionTypes)
static::formatValue($value),
static::formatTypesOf($optionTypes)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calling private methods must use self::, not static::, otherwise it is broken when extending the class, by trying to call it on the child class

@cleentfaar
Copy link
Author

@stof @cordoval fixed

@@ -79,13 +98,13 @@ class Options implements \ArrayAccess, \Iterator, \Countable
public static function resolve(array $options, $defaults)
{
if (is_array($defaults)) {
static::validateNames($options, $defaults, true);
self::validateNames($options, $defaults, true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validateNames() is public. Therefore, static must be kept here.

@webmozart
Copy link
Contributor

This is replaced by #12156.

@webmozart webmozart closed this Oct 16, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants