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

Throw any error unrelated to Zod #504

Closed
wants to merge 1 commit into from
Closed

Throw any error unrelated to Zod #504

wants to merge 1 commit into from

Conversation

stephan281094
Copy link

This pull request makes sure that errors that are not of type ZodError are thrown. It's possible for errors other than ZodError to occur when using things like .refine (for instance by referencing the property of a non-existent item in an array). Currently, when this happens, you get the following error:

TypeError: undefined is not an object (evaluating 'e.length')

This took me a long time to debug today, because it was not clear where this error was coming from, nor was it very descriptive. Hopefully this change will save someone's time in the future!

Please let me know if any changes are necessary. I'll gladly update the pull request.

@jorisre
Copy link
Member

jorisre commented Feb 8, 2023

Error should be associated to a field (by its name). That's how work resolvers with react-hook-form.
@bluebill1049 what's your thoughts?

@bluebill1049
Copy link
Member

Yes, @jorisre let's keep it that way unless we have a general implementation for all resolvers. This would create inconsistency between all.

@stephan281094
Copy link
Author

Error should be associated to a field (by its name). That's how work resolvers with react-hook-form.
@bluebill1049 what's your thoughts?

Thank you for the quick reply! I'm not sure I understand. Are you saying instead of checking whether an error is of type ZodError, it should check for a different type of error?

@stale
Copy link

stale bot commented Mar 12, 2023

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 ❤️

@stale stale bot added the stale label Mar 12, 2023
@stephan281094
Copy link
Author

Error should be associated to a field (by its name). That's how work resolvers with react-hook-form.
@bluebill1049 what's your thoughts?

Thank you for the quick reply! I'm not sure I understand. Are you saying instead of checking whether an error is of type ZodError, it should check for a different type of error?

Let me know what changes are required for this to get through, or whether you want to close this, thank you!

@stale stale bot removed the stale label Mar 12, 2023
@jorisre
Copy link
Member

jorisre commented Mar 19, 2023

@stephan281094 resolvers return errors that are linked to a field by its path. In your case, your refine isn't linked to a field.
The correct way to use refine with react-hook-form is to put manually a path:

https://zod.dev/?id=customize-error-path

schema.refine((obj) => obj.password === obj.repeatPassword, {
    message: 'Passwords do not match',
    path: ['confirm'], // 👈 reference the field
  })

@stephan281094
Copy link
Author

@stephan281094 resolvers return errors that are linked to a field by its path. In your case, your refine isn't linked to a field. The correct way to use refine with react-hook-form is to put manually a path:

https://zod.dev/?id=customize-error-path

schema.refine((obj) => obj.password === obj.repeatPassword, {
    message: 'Passwords do not match',
    path: ['confirm'], // 👈 reference the field
  })

Thanks for clarifying, Joris. I understand that errors thrown when z.refine returns false should be linked to fields. I'm however not talking about Zod errors, I'm talking about non-Zod errors. Right now, the code always expects a ZodError to be thrown, when different kinds of errors may also be thrown.

For example, the following piece of code:

schema.refine((obj) => {
  return obj.non.existing.property
})

throws:

TypeError: undefined is not an object (evaluating 'e.length')

when it should be throwing:

TypeError: undefined is not an object (evaluating 'obj.non.existing')

The Zod resolver currently, incorrectly assumes the error that gets caught, is always a Zod Error. In the code you can see error.isEmpty being accessed, which doesn't exist on non-Zod Error objects. This leads to parseErrorSchema being called with the non-existing error.errors object, resulting in an incorrect error message.

I hope I've been able to better clarify the issue this pull request is solving.

@jorisre
Copy link
Member

jorisre commented Mar 19, 2023

That's correct, we do something similar for the yup resolver. Can you fix conflicts? Thank you

@jorisre
Copy link
Member

jorisre commented Mar 20, 2023

Here is #528 that fix all resolvers

@jorisre
Copy link
Member

jorisre commented Mar 20, 2023

Cloising in favor of #528

@jorisre jorisre closed this Mar 20, 2023
@stephan281094
Copy link
Author

Here is #528 that fix all resolvers

Amazing, thank you! 🙌

@stephan281094 stephan281094 deleted the zod-error branch March 20, 2023 10:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants