Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
[Validator] Added error codes to all constraints with multiple error causes#12021
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
Koc commentedSep 24, 2014
What way to determinate what concrete constraint failed? |
Koc commentedSep 24, 2014
Maybe can we use reflection for generation error names from constants name by they values? |
webmozart commentedSep 25, 2014
@Koc Just check Reflection is slow. We won't change the error codes very often, so an explicit mapping should be fine. |
stof commentedSep 25, 2014
@fabpot can you merge older branches into master so that this PR can be rebased ? It will be easier to review it when the diff does not include the changes of previous PRs |
webmozart commentedSep 25, 2014
stof commentedSep 25, 2014
I think you used the wrong issue number in your comment |
webmozart commentedSep 25, 2014
@stof No I haven't... ;) |
stof commentedSep 25, 2014
you cheated 😄 |
…lper for BC with the 2.4 API (webmozart)This PR was merged into the 2.5 branch.Discussion----------[Validator] Added ConstraintValidator::buildViolation() helper for BC with the 2.4 API| Q | A| ------------- | ---| Bug fix? | no| New feature? | no| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets | -| License | MIT| Doc PR | -This PR adds a `buildViolation()` helper method to the base `ConstraintValidator` to remove the API checks (2.4 vs. 2.5) from the constraint validator implementations. Once the 2.4 API is removed, this helper method will be removed as well.**Todos**- [x] Backport changes from#12021Commits-------6b0c24a [Validator] Added ConstraintValidator::buildViolation() helper for BC with 2.4 API
webmozart commentedSep 25, 2014
This is rebased now. I also improved the UUID validator to give more helpful error codes. |
webmozart commentedSep 25, 2014
Ready for review+merge. ping @symfony/deciders |
de62121 to18d8eceComparewebmozart commentedSep 25, 2014
@weaverryan Could you check the names of the error constants for linguistic mistakes? |
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.
could it be private instead ?
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.
hmm, no sorry, forget it, it overwrites the parent ones
mickaelandrieu commentedSep 25, 2014
👍 |
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.
This will cause issues in the form binding, as it checks for$allowNonSynchronized = Form::ERROR_NOT_SYNCHRONIZED === $violation->getCode();, andForm::ERROR_NOT_SYNCHRONIZED is1 as well.
However, we probably need to check the violation constraint instead to ensure it is a Form constraint (we cannot be sure that the whole ecosystem will never reuse the value1)
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.
Good catch!
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.
Fixed
webmozart commentedSep 26, 2014
I changed all constant names as suggested.@weaverryan I'd still like to have a check from a native speaker, if possible. @Tobion I removed the internal flag and changed the type hint to "int" for |
Tobion commentedSep 26, 2014
there are still some |
webmozart commentedSep 30, 2014
@Tobion We can't change those. Since the old
For generic code that must work with userland constraints also, you should wrap the call to |
webmozart commentedSep 30, 2014
ping @symfony/deciders I'd like to merge this today. |
…multiple error causes (webmozart)This PR was merged into the 2.6-dev branch.Discussion----------[Validator] Added error codes to all constraints with multiple error causes| Q | A| ------------- | ---| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets |#7276| License | MIT| Doc PR | TODOThis PR depends on#12015 and#12016 being merged first. However, a few changes in52cb7df first must be backported to#12016.This PR introduces error codes for all constraints with multiple error paths. This lets you determine what exactly the reason was that a constraint failed:```php$validator = Validation::createValidator();$violations = $validator->validate('0-4X19-92619812', new Isbn());foreach ($violations as $violation) { var_dump($violation->getCode()); // => int(3) var_dump(Isbn::getErrorName($violation->getCode())); // => string(24) "ERROR_INVALID_CHARACTERS" var_dump($violation->getConstraint()->getErrorName($violation->getCode())); // => string(24) "ERROR_INVALID_CHARACTERS"}```The `getErrorName()` method is especially helpful for REST APIs, where you can return both an error code and a description of that error now.**Todos**- [x] Backport a few structural changes to#12016- [x] Update constraints outside of the Validator component- [x] Rebase on master (after merging#12015 and#12016)Commits-------3b50bf2 [Validator] Added error codes to all constraints with multiple error causes
Tobion commentedSep 30, 2014
@webmozart I still don't see your argument that the error code can be used in a REST API. The error code is not unique, so if a users reports he received |
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 don't think it makes sense to only change it toint here when every other code in the validator component is said to bemixed.
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.
btw,https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Validator/ConstraintViolation.php#L128 is also not safe to do when code is mixed.
webmozart commentedSep 30, 2014
@Tobion Of course you have to provide the name of the failing constraint as well, otherwise the code is useless. Wecould make sure that the errors are unique by collecting them in a single class instead of within the individual constraints. Do you think that is a better solution? Sketch: namespaceSymfony\Component\Validator;finalclass Error{constFILE_NOT_FOUND =100;constFILE_EMPTY =101;constIBAN_TOO_SHORT =200;privatefunction__construct() {... }}$context->buildViolation('Error!') ->setCode(Error::FILE_NOT_FOUND) ->addViolation();if (Error::FILE_NOT_FOUND ===$violation->getCode()) {// ...} |
Tobion commentedSep 30, 2014
Well, the name must not really be unique as well. For example there are some as generic as Collecting errors in one place is worse IMO and also would not work with custom constraints anyway. |
merk commentedSep 30, 2014
I dont see an issue with providing the constraint name along with the error code? It seems much more flexible than collecting the error codes into a single class or trying to ensure they're unique. |
aeoris commentedOct 1, 2014
@webmozart thanks for your work on that. Just my two cents: I still sort of prefer something unique-ish like an UUID, but I guess the constraint name + code is enough for me. I don't see the need of dealing with two keys (constraint, code) when the API consumers -which would be my main use case for this feature- can do fine with just a single one (code/uuid). |
webmozart commentedOct 1, 2014
@Tobion I understand from your reply that you're not happy with the current solution, but what do you suggest to improve it? |
stof commentedOct 1, 2014
IMO, the solution depends on the use case. For many cases, the error name is probably a better fit for the REST API than the numeric code. It will also make it easier to understand for people debugging their usage (as the error name can be understood). To make it useful, we just need to make sure that we don't use the same name for things which have actually different meaning (but this is not likely for names). But we don't need to ensure uniqueness. |
lucascourot commentedOct 23, 2014
👍 This reminds me of an issue I opened on the FosRestBundle repo few weeks agoFriendsOfSymfony/FOSRestBundle#842. I needed an error code (error constant name or error numeric code) for my REST API as I wanted to obtain something like thishttp://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#errors By the way, have you seen this bundle which helps handling errors in REST APIs?https://github.com/TheBigBrainsCompany/TbbcRestUtilBundle/blob/master/README.md |
stanlemon commentedOct 23, 2014
This would be awesome to have! 👍 |
lsmith77 commentedOct 23, 2014
@lucascourot there are quite a few form related tickets open on the FOSRestBundle that need attention. Since I am personally not using the form component with FOSRestBundle (mostly because a large chunk of the REST related stuff I do is read only APIs) I need helping hands. |
lucascourot commentedOct 23, 2014
@lsmith77 I think my issue was mainly related to the fact that it wasn't possible to associate an error code to a validation constraint. Unless you extended each constraint class and added an error code attribute. |
webmozart commentedOct 23, 2014
@stanlemon This is merged already. The question is: Right now, only those constraints which have multiple error causes have error codes. For example: // caused by NotNull$violation->getCode();// => null// caused by Length$violation->getCode()// => 1Length::getErrorName($violation->getCode());$violation->getConstraint()->getErrorName($violation->getCode());// => "TOO_SHORT_ERROR" Also, neither the numeric codes nor the error names are globally unique. So there are many constraints with the error code 1, there are also many constraints with a TOO_SHORT_ERROR. Hence the API output is only useful if you indicate the code/error nametogether with the name of the constraint causing that error. Now my question: Is this a problem? Or do you prefer globally unique codes so that you know from the code exactly which constraint caused the error and what error it is? We could achieve this by replacing integers by UUIDs. |
stof commentedOct 23, 2014
@webmozart but TOO_SHORT_ERROR is clear in all cases even if it is used in several places, because it has the same meaing in all cases: the value is too short |
Tobion commentedOct 23, 2014
@stof I think you missed to point of the codes. That the value is too short is already clear from the |
stof commentedOct 23, 2014
@Tobion but for Rest API, most of the time, this code will be enough (while relying on the message itself to identify it is too short is not, given that the message can be updated to fix a typo in the wording for instance) |
Tobion commentedOct 23, 2014
Yes "most of the time". But I prefer a system that covers it's intended functionality all the time. |
Tobion commentedAug 22, 2017
For reference the follow up change:#15154 |
This PR depends on#12015 and#12016 being merged first. However, a few changes in52cb7df first must be backported to#12016.
This PR introduces error codes for all constraints with multiple error paths. This lets you determine what exactly the reason was that a constraint failed:
The
getErrorName()method is especially helpful for REST APIs, where you can return both an error code and a description of that error now.Todos