Skip to content
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

Maintain AJV properties when custom validator is in use. #2002

Closed
wants to merge 5 commits into from
Closed

Maintain AJV properties when custom validator is in use. #2002

wants to merge 5 commits into from

Conversation

RoboPhred
Copy link

@RoboPhred RoboPhred commented Aug 19, 2020

Reasons for making this change

This fixes the issue where AJV errors are stripped of important properties when a custom validator is in use.

This fixes issue #1596

Checklist

  • I'm updating documentation
  • I'm adding or updating code
    • I've added and/or updated tests
    • I've updated docs if needed
  • I'm adding a new feature
    • I've updated the playground with an example use of the feature

expect(errors[0].stack).eql("pass2: passwords don't match.");
expect(errors).to.have.length.of(2);
expect(errors[0].stack).eql(".numberWithMinimum should be >= 5");
expect(errors[1].stack).eql("pass2: passwords don't match.");
Copy link
Author

@RoboPhred RoboPhred Aug 19, 2020

Choose a reason for hiding this comment

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

Note how the stack message is subtly different here:
RJSF custom errors use fieldName: message
AJV errors use .field.path message

I am slightly worried that this might be considered a breaking change, as previously our mangling of AJV errors would have changed the stack message to the RJSF format, so anything expecting the stack to remain the same will suffer.

However, if someone did not make use of custom validation, then I think all errors would be using the AJV error form. This might indicate we should in fact change custom validation stacks to match the AJV format, to make it consistent across both usages.

I would like some input on how to approach this. My recommendation is changing RJSF to use AJV style messages in all cases, to make custom validation use the same format as non-custom validation. But if we want to be strictly backwards compatible with these messages, we can re-mangle AJV errors only when custom validation is being used, and leave the user to extract the error path from the now-usable AJV error properties.

Copy link
Member

@epicfaace epicfaace Aug 30, 2020

Choose a reason for hiding this comment

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

My recommendation is changing RJSF to use AJV style messages in all cases

I like this approach. I think rjsf is due for a new breaking change soon (there are several PRs that would require breaking changes but are probably needed), so I think we should be fine if we just change this PR to do this and then release in v3.x.

Copy link
Author

Choose a reason for hiding this comment

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

I switched custom errors to use AJV style error messages.

Note that errors on the root now show up with a single dot, as in ". This is a root error". This appears a bit strange, but is indeed the way AJV shows root errors.

packages/core/src/validate.js Outdated Show resolved Hide resolved
packages/core/src/validate.js Outdated Show resolved Hide resolved
expect(errors[0].stack).eql("pass2: passwords don't match.");
expect(errors).to.have.length.of(2);
expect(errors[0].stack).eql(".numberWithMinimum should be >= 5");
expect(errors[1].stack).eql("pass2: passwords don't match.");
Copy link
Member

@epicfaace epicfaace Aug 30, 2020

Choose a reason for hiding this comment

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

My recommendation is changing RJSF to use AJV style messages in all cases

I like this approach. I think rjsf is due for a new breaking change soon (there are several PRs that would require breaking changes but are probably needed), so I think we should be fine if we just change this PR to do this and then release in v3.x.

@epicfaace epicfaace added this to In progress in v3.x via automation Aug 30, 2020
RoboPhred and others added 3 commits August 31, 2020 09:33
Co-authored-by: Ashwin Ramaswami <aramaswamis@gmail.com>
BREAKING CHANGE:
This changes the message format of custom validation errors.
@@ -80,21 +80,22 @@ function toErrorSchema(errors) {
}, {});
}

export function toErrorList(errorSchema, fieldName = "root") {
// XXX: We should transform fieldName as a full field path string.
export function toErrorList(errorSchema, fieldPath = []) {
Copy link
Member

Choose a reason for hiding this comment

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

Sorry, I'm a bit confused as to what the changes in toErrorList have to do with fixing #1596. Doesn't the change in line 259 already ensure that the original error list is untouched?

Copy link
Author

@RoboPhred RoboPhred Mar 11, 2021

Choose a reason for hiding this comment

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

This change is talked about in the above comment

I made this change on approval from your reply

toErrorList in its original form only tracked the current field's name.
For example, given an object:

{
  foo: {
    bar: null
  },
  baz: {
    bar: "hello world"
  }
}

where foo.bar must be a string, the old version would generate an error:
bar: value must be a string.

However, this is not clear on what field received the error (there are two 'bar' properties, and it does not specify which one). It is also inconsistent with AJV's own error format.

This change generates messages in the same format as AJV, by giving a dot-separated path to the field. It's error will be:
.foo.bar value must be a string

Copy link
Member

Choose a reason for hiding this comment

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

Ah, thanks for the pointer.

packages/core/src/validate.js Outdated Show resolved Hide resolved
Copy link
Member

@epicfaace epicfaace left a comment

Choose a reason for hiding this comment

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

@RoboPhred , since this is a breaking change, can you add an entry to the 3.x upgrade guide that explains to users what has changed and what they may need to change in their own code?

The guide isn't yet on the master branch (it's in #2211), but here's the version of the guide that's in that branch: https://github.com/rjsf-team/react-jsonschema-form/blob/26d34051bbc063777645aa825ed4192e260930ab/docs/3.x%20upgrade%20guide.md You can just create the docs/3.x upgrade guide.md file on this branch.

@saadq
Copy link
Contributor

saadq commented Jul 13, 2021

Hi all, wanted to check on the status of this PR. What's still needed for this change to get merged in? Is it just updating the upgrade guide?

@penx
Copy link
Collaborator

penx commented Sep 5, 2021

@saadq looks like it missed v3 so it's on the roadmap for v4: #2437

@AlimovSV
Copy link

AlimovSV commented Mar 7, 2022

Any progress?

@heath-freenome
Copy link
Member

@RoboPhred With the upcoming beta 5 that already has a bunch of breaking changes, are you willing to port this to the rjsf-v5 branch into the validator-ajv6 package?

heath-freenome added a commit to heath-freenome/react-jsonschema-form that referenced this pull request Aug 26, 2022
…f v5

- Added a new `mergeValidationData()` method in `@rjsf/utils` to handle the appending of errors onto the end of the validationData from an additional error schema
  - Added this to the `schema` directory `index.ts` along with exposing it on the `SchemaUtils` type and implementation
  - Also fixed the type of `toErrorList()` in `ValidatorType` to change from `fieldName: string` to `fieldPath: string[]`
  - Added reusable `mergeValidationDataTest.ts`, calling it in the utils
- Update the `@rjsf/validator-ajv6` to pick up the breaking change from rjsf-team#2002 around `AJV6Validator.toErrorList()`
  - Also modified the `validateFormData()` function to return the result of `mergeValidationData()` when the user has a custom validator
  - Updated tests for the new structure of the `toErrorList()` data
  - Also updated the `schema.tests` to add the new `mergeValidationDataTest()`
- Updated `Form` to use the `mergeValidationData()` function in the few places where `extraErrors` was being merged into the schema validation
  - Updated tests for the new structor of the `toErrorList()` data
- Updated the `CHANGELOG.md` to describe this fix
- Updated the `5.x upgrade guide.md` to describe all the new utility functions added
- Updated the `validation.md` documentation for the `ErrorListTemplate` change along with making the `RJSFValidationError` interface describe the optional properties
heath-freenome added a commit to heath-freenome/react-jsonschema-form that referenced this pull request Aug 26, 2022
…f v5

- Added a new `mergeValidationData()` method in `@rjsf/utils` to handle the appending of errors onto the end of the validationData from an additional error schema
  - Added this to the `schema` directory `index.ts` along with exposing it on the `SchemaUtils` type and implementation
  - Also fixed the type of `toErrorList()` in `ValidatorType` to change from `fieldName: string` to `fieldPath: string[]`
  - Added reusable `mergeValidationDataTest.ts`, calling it in the utils
- Update the `@rjsf/validator-ajv6` to pick up the breaking change from rjsf-team#2002 around `AJV6Validator.toErrorList()`
  - Also modified the `validateFormData()` function to return the result of `mergeValidationData()` when the user has a custom validator
  - Updated tests for the new structure of the `toErrorList()` data
  - Also updated the `schema.tests` to add the new `mergeValidationDataTest()`
- Updated `Form` to use the `mergeValidationData()` function in the few places where `extraErrors` was being merged into the schema validation
  - Updated tests for the new structor of the `toErrorList()` data
- Updated the `CHANGELOG.md` to describe this fix
- Updated the `5.x upgrade guide.md` to describe all the new utility functions added
- Updated the `validation.md` documentation for the `ErrorListTemplate` change along with making the `RJSFValidationError` interface describe the optional properties
heath-freenome added a commit to heath-freenome/react-jsonschema-form that referenced this pull request Aug 26, 2022
…f v5

- Added a new `mergeValidationData()` method in `@rjsf/utils` to handle the appending of errors onto the end of the validationData from an additional error schema
  - Added this to the `schema` directory `index.ts` along with exposing it on the `SchemaUtils` type and implementation
  - Also fixed the type of `toErrorList()` in `ValidatorType` to change from `fieldName: string` to `fieldPath: string[]`
  - Added reusable `mergeValidationDataTest.ts`, calling it in the utils
- Update the `@rjsf/validator-ajv6` to pick up the breaking change from rjsf-team#2002 around `AJV6Validator.toErrorList()`
  - Also modified the `validateFormData()` function to return the result of `mergeValidationData()` when the user has a custom validator
  - Updated tests for the new structure of the `toErrorList()` data
  - Also updated the `schema.tests` to add the new `mergeValidationDataTest()`
- Updated `Form` to use the `mergeValidationData()` function in the few places where `extraErrors` was being merged into the schema validation
  - Updated tests for the new structor of the `toErrorList()` data
- Updated the `CHANGELOG.md` to describe this fix
- Updated the `5.x upgrade guide.md` to describe all the new utility functions added and describe util.js and validator.js breaking changes
- Updated the `validation.md` documentation for the `ErrorListTemplate` change along with making the `RJSFValidationError` interface describe the optional properties
heath-freenome added a commit that referenced this pull request Aug 26, 2022
* Fixed #1596 by adapting the fix from #2002 into rjsf v5
- Added a new `mergeValidationData()` method in `@rjsf/utils` to handle the appending of errors onto the end of the validationData from an additional error schema
  - Added this to the `schema` directory `index.ts` along with exposing it on the `SchemaUtils` type and implementation
  - Also fixed the type of `toErrorList()` in `ValidatorType` to change from `fieldName: string` to `fieldPath: string[]`
  - Added reusable `mergeValidationDataTest.ts`, calling it in the utils
- Update the `@rjsf/validator-ajv6` to pick up the breaking change from #2002 around `AJV6Validator.toErrorList()`
  - Also modified the `validateFormData()` function to return the result of `mergeValidationData()` when the user has a custom validator
  - Updated tests for the new structure of the `toErrorList()` data
  - Also updated the `schema.tests` to add the new `mergeValidationDataTest()`
- Updated `Form` to use the `mergeValidationData()` function in the few places where `extraErrors` was being merged into the schema validation
  - Updated tests for the new structor of the `toErrorList()` data
- Updated the `CHANGELOG.md` to describe this fix
- Updated the `5.x upgrade guide.md` to describe all the new utility functions added and describe util.js and validator.js breaking changes
- Updated the `validation.md` documentation for the `ErrorListTemplate` change along with making the `RJSFValidationError` interface describe the optional properties

* - Responded to reviewer feedback... also, removed the `:` after the property in the `stack` to match AJV stack, adding `message` to also match AJV
- Added migration guide changes
heath-freenome added a commit to heath-freenome/react-jsonschema-form that referenced this pull request Aug 27, 2022
…f v5 (rjsf-team#3047)

* Fixed rjsf-team#1596 by adapting the fix from rjsf-team#2002 into rjsf v5
- Added a new `mergeValidationData()` method in `@rjsf/utils` to handle the appending of errors onto the end of the validationData from an additional error schema
  - Added this to the `schema` directory `index.ts` along with exposing it on the `SchemaUtils` type and implementation
  - Also fixed the type of `toErrorList()` in `ValidatorType` to change from `fieldName: string` to `fieldPath: string[]`
  - Added reusable `mergeValidationDataTest.ts`, calling it in the utils
- Update the `@rjsf/validator-ajv6` to pick up the breaking change from rjsf-team#2002 around `AJV6Validator.toErrorList()`
  - Also modified the `validateFormData()` function to return the result of `mergeValidationData()` when the user has a custom validator
  - Updated tests for the new structure of the `toErrorList()` data
  - Also updated the `schema.tests` to add the new `mergeValidationDataTest()`
- Updated `Form` to use the `mergeValidationData()` function in the few places where `extraErrors` was being merged into the schema validation
  - Updated tests for the new structor of the `toErrorList()` data
- Updated the `CHANGELOG.md` to describe this fix
- Updated the `5.x upgrade guide.md` to describe all the new utility functions added and describe util.js and validator.js breaking changes
- Updated the `validation.md` documentation for the `ErrorListTemplate` change along with making the `RJSFValidationError` interface describe the optional properties

* - Responded to reviewer feedback... also, removed the `:` after the property in the `stack` to match AJV stack, adding `message` to also match AJV
- Added migration guide changes
@heath-freenome
Copy link
Member

Refactored into v5 beta via #3047

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
v3.x
  
In progress
Development

Successfully merging this pull request may close these issues.

None yet

6 participants