Skip to content
This repository has been archived by the owner on Nov 16, 2020. It is now read-only.

Not possible to get list of keypaths that failed validation #26

Closed
0xTim opened this issue Jun 22, 2018 · 1 comment
Closed

Not possible to get list of keypaths that failed validation #26

0xTim opened this issue Jun 22, 2018 · 1 comment

Comments

@0xTim
Copy link
Member

0xTim commented Jun 22, 2018

When Validations.run() is called, it collects all failures in a ValidationErrors object, which is then thrown as the final result (unless all validations passed, of course). Unfortunately, ValidationErrors is fileprivate, making it impossible to retrieve the array of individual ValidationErrors that occurred. This, in turn, makes it impossible to determine which specific validations passed or failed in calling code save by parsing the human-readable reason string, hardly the most desirable solution. To make matters worse, Validations<M>.storage is also fileprivate, making it impossible to reimplement a custom version of run() to get around the problem for code where "which key failed validation" matters to the program logic. Consider, for example, the case of a RESTful JSON API which defines different integer response codes for different input errors. Even aside the issue of more than one validation potentially failing (which can be addressed by simply taking the first to fail or by any of several other means), knowing which key paths failed validation is critical to such an API. A trivial fix is to make ValidationErrors and its errors property both public. A more robust solution probably entails a minor API redesign.

Additionally, even if the matter of getting at the list of failures is addressed, the idiomatic form for determining which key path was affected looks like:

if let validationError = error as? ValidationError, try validationError.path == InputModel.decodeProperty(forKey: \.criticalInputValue)?.path {

Or:

catch let validationError as ValidationError where try! validationError.path == InputModel.decodeProperty(forKey: \.criticalInputValue)?.path {

Both of these are rather unwieldy at best. One alternative would be for a ValidationError to track the Validator which created it, and for Validations to maintain the mapping of keypaths to arrays of Validators, so a simple comparison of PartialKeyPath<M>s can be used instead of relying upon the reflection decoder. This feels like an unwieldy solution to an unwieldy problem, but nothing better comes immediately to mind.

Additionally, a variant of .run() which throws the first validation error instead of gathering all of them might also be useful.

@cb1674
Copy link

cb1674 commented Nov 6, 2018

This is definitely a must-have.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants