-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
feat: add errorformatter #1273
feat: add errorformatter #1273
Conversation
π¦ Changeset detectedLatest commit: 9fd84b3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The latest updates on your projects. Learn more about Vercel for Git βοΈ
|
Running Lighthouse audit... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love it, we should add docs for this too before merging
Good shout! What do you think would be the best docs for this? Inferring errorsBy default, tRPC sets up an error formatter that let's you infer your Zod Errors if you get validation errors on the backend. Example usage: function MyComponent() {
const mutation = api.post.create.useMutation();
return (
<form>
<input name="title" />
{mutation.error?.data?.zodError?.fieldErrors.title ? (
<span className="mb-8 text-red-500">
{mutation.error.data.zodError.fieldErrors.title}
</span>
) : null}
...
</form>
);
} Or do you have a better idea? |
Looks good to me |
docs text should be "lets" instead of "let's" realized while reading this pr that maybe some of the text in trpc.ts could be made a bit easier to understand overall, but thats for another pr |
Co-authored-by: Christopher Ehrlich <[email protected]>
This not being in yet just embarrassed the hell out of me during a recording π |
I think we can merge this now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shipppp
Has anyone run into the scenario where you are updating a resource and so need a data payload but also an id to actually find the resource update, the function would look something like this: update: protectedProcedure.input(z.object({ id: z.string(), data: customSchemaForResource })).mutation(.. now when using the errorFormatter/flatten thing from zod, any errors within the data schema validator get flattened into a "data" key, and so on the frontend you dont know which field caused the error. What are peoples practices for handling this? |
What do you mean? The current formatter would return this if you send a number instead of a string to the default query on a fresh app: // query this:
const hello = api.example.hello.useQuery({ text: 1 });
// would result in this error:
hello.error?.shape?.data.zodError;
{
"formErrors": [],
"fieldErrors": {
"text": [
"Expected string, received number"
]
}
} so you have your fieldErrors with the fields that failed. I think this should be enough for the default case but obviously you can add your own custom logic to handle your own needs beyond this |
@juliusmarminge Just curious, how would you structure your trpc input when updating a "todo", for example? as you'll need an ID of some sort and then the actual data to update, do you just put the ID alongside all the fields that are being updated? The reason I ask, is because if you have a nested object in a Zod schema, the flatten function removes all the nested keys and puts all the error message of the nested object into the top level key. for example: z.object({
id: z.string(),
data: z.object({
name: z.string(),
description: z.string()
})
}) If you flatten this, name and description get flattened into the "data" key: {
"formErrors": [],
"fieldErrors": {
"data": [ // if the name was a number, it still shows up on the data key
"Expected string, received number"
]
}
} |
Yea probably, i had some procedure recently which posted a review on a product which was something like create: protectedProcedure
.input(z.object({
productId: z.string(),
text: z.string().min(10),
rating: z.number().min(0).max(5),
})
.mutation(...) |
Yeah exactly so just need to make sure to extract it from the input before updating a database record for example, as Ive typically been doing: await prisma.todo.update({where: { id: input.id }, data: input.data }) Was just wondering how people where structuring their inputs, thanks for the help! P.s. the reason I was trying to avoid merging the ID next to the data, is because if the data object is quite large, and reused in many places, I abstracted into a const somewhere, but for updating I now need to merge the ID into this? p.p.s was easy enough to merge actually taskSchema.merge(z.object({id: z.string()})) |
Ah I see... Something like this: export const exampleRouter = createTRPCRouter({
hello: publicProcedure
.input(
z.object({
id: z.string(),
data: z.object({
text: z.string().min(3),
}),
})
)
.query(({ input }) => {
return {
greeting: `Hello ${input.data.text}`,
};
}),
}); would return an error like this if some field within the data object is invalid: {
"formErrors": [],
"fieldErrors": {
"data": [
"String must contain at least 3 character(s)"
]
}
} Hmm... not sure if you can write a better error formatter to handle that form of input structure |
Yeah exactly, I edited my previous comment showing a workaround ill go for as I really dont wana write my own formatter :P |
The {
"_errors": [],
"id": {
"_errors": [
"Expected string, received number"
]
},
"data": {
"_errors": [],
"text": {
"_errors": [
"String must contain at least 3 character(s)"
]
}
}
} which you could probably work with to make it work for your usecase |
Yeah looked into this but was getting some issues with TS typings, but will investigate more, thanks for help! Is there a way to get type safe access to the field errors? as p.s would be real nice if t3-stack could show examples of typesafe error handling |
* add errorformatter * add docs * changeset * Update www/src/pages/en/usage/trpc.md Co-authored-by: Christopher Ehrlich <[email protected]> --------- Co-authored-by: Christopher Ehrlich <[email protected]> Co-authored-by: Shoubhit Dash <[email protected]>
Closes #
β Checklist
Changelog
[Short description of what has changed]
Screenshots
[Screenshots]
π―