diff --git a/CHANGELOG.md b/CHANGELOG.md index 84d5b31251..06bb9a727f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ should change the heading of the (upcoming) version to include a major version b - Updated `Experimental_DefaultFormStateBehavior` to add a new `constAsDefaults` option - Updated `getDefaultFormState()` to use the new `constAsDefaults` option to control how const is used for defaulting, fixing [#4344](https://github.com/rjsf-team/react-jsonschema-form/issues/4344), [#4361](https://github.com/rjsf-team/react-jsonschema-form/issues/4361) and [#4377](https://github.com/rjsf-team/react-jsonschema-form/issues/4377) - Use `experimental_customMergeAllOf` option in functions that have previously missed it. +- Updated `ErrorSchemaBuilder` methods `addErrors` and `setErrors` to prevent duplicate error messages. ## @rjsf/validator-ajv8 diff --git a/packages/utils/src/ErrorSchemaBuilder.ts b/packages/utils/src/ErrorSchemaBuilder.ts index ab9cc2169d..5a39254fb0 100644 --- a/packages/utils/src/ErrorSchemaBuilder.ts +++ b/packages/utils/src/ErrorSchemaBuilder.ts @@ -75,9 +75,9 @@ export default class ErrorSchemaBuilder { } if (Array.isArray(errorOrList)) { - errorsList.push(...errorOrList); + set(errorBlock, ERRORS_KEY, [...new Set([...errorsList, ...errorOrList])]); } else { - errorsList.push(errorOrList); + set(errorBlock, ERRORS_KEY, [...new Set([...errorsList, errorOrList])]); } return this; } @@ -93,7 +93,7 @@ export default class ErrorSchemaBuilder { setErrors(errorOrList: string | string[], pathOfError?: string | (string | number)[]) { const errorBlock: ErrorSchema = this.getOrCreateErrorBlock(pathOfError); // Effectively clone the array being given to prevent accidental outside manipulation of the given list - const listToAdd = Array.isArray(errorOrList) ? [...errorOrList] : [errorOrList]; + const listToAdd = Array.isArray(errorOrList) ? [...new Set([...errorOrList])] : [errorOrList]; set(errorBlock, ERRORS_KEY, listToAdd); return this; } diff --git a/packages/utils/test/ErrorSchemaBuilder.test.ts b/packages/utils/test/ErrorSchemaBuilder.test.ts index 54d587e0b1..776579c7b7 100644 --- a/packages/utils/test/ErrorSchemaBuilder.test.ts +++ b/packages/utils/test/ErrorSchemaBuilder.test.ts @@ -240,6 +240,24 @@ describe('ErrorSchemaBuilder', () => { it('resetting error restores things back to an empty object', () => { expect(builder.resetAllErrors().ErrorSchema).toEqual({}); }); + it('adding duplicated error string with a path puts only the unique errors at the path', () => { + builder.addErrors([AN_ERROR], STRING_PATH); + builder.addErrors([AN_ERROR], STRING_PATH); + expect(builder.ErrorSchema).toEqual({ + [STRING_PATH]: { + [ERRORS_KEY]: [AN_ERROR], + }, + }); + }); + + it('setting duplicated error string with a path puts only the unique errors at the path', () => { + builder.setErrors([AN_ERROR, AN_ERROR], STRING_PATH); + expect(builder.ErrorSchema).toEqual({ + [STRING_PATH]: { + [ERRORS_KEY]: [AN_ERROR], + }, + }); + }); }); describe('using initial schema', () => { let builder: ErrorSchemaBuilder;