-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Validator] catch any UnexpectedValueException on validation #27917
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
xabbuh
commented
Jul 10, 2018
•
edited
Loading
edited
Q | A |
---|---|
Branch? | master |
Bug fix? | no |
New feature? | yes |
BC breaks? | no |
Deprecations? | no |
Tests pass? | yes |
Fixed tickets | #12312 |
License | MIT |
Doc PR |
This change would fix issues like #14943 (and many other related issues). I didn't add any tests yet, but would like to get some feedback first as setting them up seems to be quite complex. I am not sure if anyone could have actually relied on the previous behaviour. If we think that this was a supported use case, we will probably have to make this feature opt-in. |
Shouldnt we, for consistency, raise a violation per case:
and basically get rid of |
Imho a validator should not throw exceptions if you ask to validate unexpected data types, that could come from user or whatever untrusted, it should just add violations. |
I agree with @ro0NL , we should handle it per case in each validator. Relates to #26477 (comment) too where I also suggested this. Handling this properly in each validator would not interrupt the validation and keep adding other violations (and answer the AllValidator issue too). |
Also i was wondering if we can somehow leverage the Maybe with some helper, it could also ease the migration of custom constraint validators. |
@ro0NL Your example in #27917 (comment) is IMO not good in terms of DX. The goal of this PR is precisely to lower the burden when writing constraint validators. But @ogizanagi has a valid point in the exception could as well have been thrown because of the wrong constraint being passed. What do you think about a different approach like the one @webmozart suggested in #12312? |
Oh wow :) @webmozart created all the tickets already :D His suggestion indeed looks very good! Except im not sure about proposed strict/loose varying in We still agree a constraint violation should be favored over an exception right?
Still.., we need to trigger type validation somewhere right? |
@ro0NL I still think it's okay to throw an exception in the validator which will then be transformed into a proper constraint violation. @ogizanagi made another good suggestion in #26477 (comment):
|
👍 for |
9d30a98
to
fac281d
Compare
PR updated with a new |
{ | ||
private $expectedType; | ||
|
||
public function __construct($value, string $expectedType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about array $expectedTypes
. Right now array or Traversable
is not really a friendly translation parameter. We should leverage the new message formatter for this :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That assumes it's all unions. It will prevent consumers to use more complicated rules in future, e.g. intersection types. Also, I'm interested how would you improve message array or Traversable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe
throw UnexpectedValueException::notUnionOf($value, $type, ...$type);
throw UnexpectedValueException::notIntersectionOf($value, $type, ...$type);
From #28645 (comment) not sure the current approach is blocking for @nicolas-grekas Alternatively, what about exposing the variables and pre-validate as such in i.e.
E.g. Also #27917 (comment) is still considerable IMHO, that solves translation messages, complex type validation and overall consistency.
I think we can simplify it by adding some util to the base class, e.g. |
Well, the main idea for this PR is not to centralise logic. I mean I would be fine with adding more code to our core constraint validators to achieve the same. The code added here is more important for individual constraint validators written for applications where users do not want to deal with more code. |
But it does exactly that, inferring the constraint violation thru exception in |
Do you think we can resolve this before the end of the month to have it in 4.2? |
From my point of view the PR is finished. Do you think we should take another direction? |
@@ -34,7 +35,7 @@ public function validate($value, Constraint $constraint) | |||
} | |||
|
|||
if (!\is_array($value) && !($value instanceof \Traversable && $value instanceof \ArrayAccess)) { | |||
throw new UnexpectedTypeException($value, 'array or Traversable and ArrayAccess'); | |||
throw new UnexpectedValueException($value, 'array or Traversable and ArrayAccess'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i still think we need to tackle this being translator friendly, it'll only work for english
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e.g. different messages like
This value should be of type {{ type }}
(generic)This value should be array accessible
This value should be iterable
This value should be a countable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about using array|(Traversable&ArrayAccess)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds like a plan yes :) the messages dont have to be pretty (tailored), but should be correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't translate exception messages
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the issue happens here: https://github.com/symfony/symfony/pull/27917/files#diff-d46c902789b437519780ee8110ecb5e9R807 (in RecursiveContextualValidator
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -34,7 +35,7 @@ public function validate($value, Constraint $constraint) | |||
} | |||
|
|||
if (!\is_array($value) && !$value instanceof \Traversable) { | |||
throw new UnexpectedTypeException($value, 'array or Traversable'); | |||
throw new UnexpectedValueException($value, 'array or Traversable'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets use iterable
here
Thank you @xabbuh. |
…dation (xabbuh) This PR was merged into the 4.2-dev branch. Discussion ---------- [Validator] catch any UnexpectedValueException on validation | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #12312 | License | MIT | Doc PR | Commits ------- fa35860 catch any UnexpectedValueException on validation
This PR was merged into the 5.4 branch. Discussion ---------- [Validator] fix the exception being thrown | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | | License | MIT An `UnexpectedValueException` is caught and transformed into a violation (`UnexpectedTypeException` indicates a misconfiguration of a constraint and is not caught). see also #27917 Commits ------- 3a8f10b fix the exception being thrown