resolvers
resolvers copied to clipboard
Fix nested error reporting
Fixes #441
@bluebill1049, is there anything else you'd like to address on this PR?
I am quite busy at the moment, but I will find some time to review it properly in the following days. thanks for the help <3
The problem is that there is no easy way to fix or monkey patch this other than maintaining a fork. Also, this is a real feature bug for those who use the all criteria.
I was having the same error on my application and I can confirm this PR solves the issue. Is there something missing so we can have this in a future release of resolvers?
@georgekaran , this is a terrible but functional workaround for the issue:
import {ValidationError} from "yup";
import {yupResolver as baseResolver} from "@hookform/resolvers/yup";
import BaseSchema from "yup/lib/schema";
/**
* Workaround for https://github.com/react-hook-form/resolvers/issues/441
*/
function fixErrorNesting(errors: Record<string, any>): Record<string, any> | any[] {
const fieldErrors: Record<string, any> = {};
for (const [key, value] of Object.entries(errors)) {
if (typeof value !== 'object' || value === null || !('ref' in value)) {
fieldErrors[key] = value;
continue;
}
if (Array.isArray(value)) {
fieldErrors[key] = value.map(fixErrorNesting);
continue;
}
if (!('0' in value)) {
fieldErrors[key] = fixErrorNesting(value);
continue;
}
const copy = {...value}
const list = [];
let index = 0;
while (index in copy) {
list.push(fixErrorNesting(copy[index]));
delete copy[index];
index++;
}
Object.assign(list, copy);
fieldErrors[key] = list;
}
return fieldErrors;
}
export const yupResolver: typeof baseResolver = (schema, schemaOptions = {}, resolverOptions = {}) => {
const schemaClone = (schema as any).clone() as BaseSchema;
const validate = schemaClone.validate.bind(schemaClone);
const validateSync = schemaClone.validateSync.bind(schemaClone);
function sortErrors<T>(error: T): T {
if (error instanceof ValidationError) {
error.inner.sort((left, right) => {
if (left.path === right.path) {
return 0;
}
return (left.path ?? '') > (right.path ?? '') ? 1 : -1
});
}
return error;
}
schemaClone.validate = async (...args) => {
try {
return await validate(...args);
} catch (error) {
throw sortErrors(error);
}
};
schemaClone.validateSync = (...args) => {
try {
return validateSync(...args);
} catch (error) {
throw sortErrors(error);
}
};
const resolver = baseResolver(schemaClone as typeof schema, schemaOptions, resolverOptions);
return async (values, context, options) => {
const result = await resolver(values, context, options);
return {
...result,
errors: fixErrorNesting(result.errors) as typeof result.errors,
}
};
};
It should definitely be fixed.
Thanks @marcospassos it worked like a charm, but it should definitely be shipped native 😕
Thank you for your contributions! This Pull Request has been automatically marked as stale because it has not had any recent activity. It will be closed if no further activity occurs. Best, RHF Team ❤️
Thank you for your contributions! This Pull Request is being closed because it has not had any recent activity. Feel free to re-open the issue and begin work again! Best, RHF Team ❤️