Skip to content

Commit c6d44dc

Browse files
dagda1heath-freenome
authored and
shijistar
committed
Fix: Better validation messages using schema/uiSchema title if it exists (rjsf-team#3337)
* use title if available for validation errors * add title tests to validator-ajv8 validator tests * use scoped lodash/get * set verbose in createAjvInstance * use parentSchema for getting title * remove . in validator tests * rename local vars * remove duplicate local var * Update packages/validator-ajv8/test/validator.test.ts Co-authored-by: Heath C <[email protected]> * use params.missingProperty for currentProperty * check uiSchema for ui:title override in transformRJSFValidationErrors * revert package-lock.json files * Update packages/validator-ajv8/src/validator.ts Co-authored-by: Heath C <[email protected]> * Update packages/validator-ajv8/src/validator.ts Co-authored-by: Heath C <[email protected]> * add getUiOptions import * remove type arguments in call to getUiOptions * revert to leading period in default stack message * revert lock files * test for ajv8 ErrorObject optional fields * use array notation get * update CHANGELOG * Update CHANGELOG.md Co-authored-by: Heath C <[email protected]> * Update packages/validator-ajv8/package.json Co-authored-by: Heath C <[email protected]> * Update packages/validator-ajv8/src/validator.ts Co-authored-by: Heath C <[email protected]> * Update packages/validator-ajv8/src/validator.ts Co-authored-by: Heath C <[email protected]> * move import * Update packages/validator-ajv8/test/validator.test.ts * Update CHANGELOG.md Co-authored-by: Heath C <[email protected]>
1 parent da5a653 commit c6d44dc

File tree

5 files changed

+315
-7
lines changed

5 files changed

+315
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ should change the heading of the (upcoming) version to include a major version b
2222

2323
## @rjsf/validator-ajv8
2424
- Remove alias for ajv -> ajv8 in package.json. This fixes [#3215](https://github.com/rjsf-team/react-jsonschema-form/issues/3215).
25+
- Updated `AJV8Validator#transformRJSFValidationErrors` to return more human readable error messages. The ajv8 `ErrorObject` message is enhanced by replacing the error message field with either the `uiSchema`'s `ui:title` field if one exists or the `parentSchema` title if one exists. Fixes [#3246](https://github.com/rjsf-team/react-jsonschema-form/issues/3246)
2526

2627
# 5.0.0-beta-16
2728

packages/validator-ajv8/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"lodash-es": "^4.17.15"
3434
},
3535
"peerDependencies": {
36-
"@rjsf/utils": "^5.0.0-beta.12"
36+
"@rjsf/utils": "^5.0.0-beta.16"
3737
},
3838
"devDependencies": {
3939
"@babel/core": "^7.20.12",

packages/validator-ajv8/src/createAjvInstance.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const AJV_CONFIG: Options = {
1212
allErrors: true,
1313
multipleOfPrecision: 8,
1414
strict: false,
15+
verbose: true,
1516
} as const;
1617
export const COLOR_FORMAT_REGEX =
1718
/^(#?([0-9A-Fa-f]{3}){1,2}\b|aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow|(rgb\(\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*\))|(rgb\(\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*\)))$/;

packages/validator-ajv8/src/validator.ts

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ import {
2121
UiSchema,
2222
ValidationData,
2323
ValidatorType,
24+
PROPERTIES_KEY,
25+
getUiOptions,
2426
} from "@rjsf/utils";
27+
import get from "lodash/get";
2528

2629
import { CustomValidatorOptionsType, Localizer } from "./types";
2730
import createAjvInstance from "./createAjvInstance";
@@ -199,20 +202,63 @@ export default class AJV8Validator<
199202
* At some point, components should be updated to support ajv.
200203
*
201204
* @param errors - The list of AJV errors to convert to `RJSFValidationErrors`
202-
* @private
205+
* @protected
203206
*/
204-
private transformRJSFValidationErrors(
205-
errors: ErrorObject[] = []
207+
protected transformRJSFValidationErrors(
208+
errors: ErrorObject[] = [],
209+
uiSchema?: UiSchema<T, S, F>
206210
): RJSFValidationError[] {
207211
return errors.map((e: ErrorObject) => {
208-
const { instancePath, keyword, message, params, schemaPath } = e;
212+
const {
213+
instancePath,
214+
keyword,
215+
params,
216+
schemaPath,
217+
parentSchema,
218+
...rest
219+
} = e;
220+
let { message = "" } = rest;
209221
let property = instancePath.replace(/\//g, ".");
210222
let stack = `${property} ${message}`.trim();
223+
211224
if ("missingProperty" in params) {
212225
property = property
213226
? `${property}.${params.missingProperty}`
214227
: params.missingProperty;
215-
stack = message!;
228+
const currentProperty: string = params.missingProperty;
229+
const uiSchemaTitle = getUiOptions(
230+
get(uiSchema, `${property.replace(/^\./, "")}`)
231+
).title;
232+
233+
if (uiSchemaTitle) {
234+
message = message.replace(currentProperty, uiSchemaTitle);
235+
} else {
236+
const parentSchemaTitle = get(parentSchema, [
237+
PROPERTIES_KEY,
238+
currentProperty,
239+
"title",
240+
]);
241+
242+
if (parentSchemaTitle) {
243+
message = message.replace(currentProperty, parentSchemaTitle);
244+
}
245+
}
246+
247+
stack = message;
248+
} else {
249+
const uiSchemaTitle = getUiOptions(
250+
get(uiSchema, `${property.replace(/^\./, "")}`)
251+
).title;
252+
253+
if (uiSchemaTitle) {
254+
stack = `'${uiSchemaTitle}' ${message}`.trim();
255+
} else {
256+
const parentSchemaTitle = parentSchema?.title;
257+
258+
if (parentSchemaTitle) {
259+
stack = `'${parentSchemaTitle}' ${message}`.trim();
260+
}
261+
}
216262
}
217263

218264
// put data in expected format
@@ -288,7 +334,7 @@ export default class AJV8Validator<
288334
): ValidationData<T> {
289335
const rawErrors = this.rawValidation<ErrorObject>(schema, formData);
290336
const { validationError: invalidSchemaError } = rawErrors;
291-
let errors = this.transformRJSFValidationErrors(rawErrors.errors);
337+
let errors = this.transformRJSFValidationErrors(rawErrors.errors, uiSchema);
292338

293339
if (invalidSchemaError) {
294340
errors = [...errors, { stack: invalidSchemaError!.message }];

0 commit comments

Comments
 (0)