T
TanStack18h ago
correct-apricot

Need Help Server Fn Error with Zod

How to properly serialized zod error to client with serverFn and tanstack query Project repo
// zod schema
const UpdateTodoIdAndName = createSelectSchema(todo, {
name: schema => schema.min(1, { error: "this is required" }),
}).pick({ id: true, name: true });

// fn
const updateTodoFn = createServerFn()
.inputValidator(UpdateTodoIdAndName)
.handler(async ({ data }) => {
const [post] = await db.update(todo).set({ name: data.name }).where(eq(todo.id, data.id)).returning();

return post;
});
// zod schema
const UpdateTodoIdAndName = createSelectSchema(todo, {
name: schema => schema.min(1, { error: "this is required" }),
}).pick({ id: true, name: true });

// fn
const updateTodoFn = createServerFn()
.inputValidator(UpdateTodoIdAndName)
.handler(async ({ data }) => {
const [post] = await db.update(todo).set({ name: data.name }).where(eq(todo.id, data.id)).returning();

return post;
});
GitHub
GitHub - gglennd/tanstack-start at feat/orm
Contribute to gglennd/tanstack-start development by creating an account on GitHub.
2 Replies
sensitive-blue
sensitive-blue16h ago
what does "properly" mean here ?
correct-apricot
correct-apricotOP7h ago
I'm trying to follow basic error to display error message on client. I first tried zod schema on inputValidator
// zod schema
const UpdateTodoIdAndName = createSelectSchema(todo, {
name: schema => schema.min(1, { error: "this is required" }),
}).pick({ id: true, name: true });

// fn
const updateTodoFn = createServerFn()
.inputValidator(UpdateTodoIdAndName)
.handler(async ({ data }) => {
const [post] = await db.update(todo).set({ name: data.name }).where(eq(todo.id, data.id)).returning();

return post;
});
// zod schema
const UpdateTodoIdAndName = createSelectSchema(todo, {
name: schema => schema.min(1, { error: "this is required" }),
}).pick({ id: true, name: true });

// fn
const updateTodoFn = createServerFn()
.inputValidator(UpdateTodoIdAndName)
.handler(async ({ data }) => {
const [post] = await db.update(todo).set({ name: data.name }).where(eq(todo.id, data.id)).returning();

return post;
});
but it console logs errors, and display nothing
# on server
Server Fn Error!

Error: [
{
"origin": "string",
"code": "too_small",
"minimum": 1,
"inclusive": true,
"path": [
"name"
],
"message": "this is required"
}
]

...
# on server
Server Fn Error!

Error: [
{
"origin": "string",
"code": "too_small",
"minimum": 1,
"inclusive": true,
"path": [
"name"
],
"message": "this is required"
}
]

...
# on client
[XHR] GET http://localhost:5173/_serverFn/src_routes_index_tsx--updateTodoFn_createServerFn_handler?payload={"t":{"t":10,"i":0,"p":{"k":["data"],"v":[{"t":10,"i":1,"p":{"k":["id","name"],"v":[{"t":0,"s":3},{"t":1,"s":""}],"s":2},"o":0}],"s":1},"o":0},"f":31,"m":[]}&createServerFn=
# on client
[XHR] GET http://localhost:5173/_serverFn/src_routes_index_tsx--updateTodoFn_createServerFn_handler?payload={"t":{"t":10,"i":0,"p":{"k":["data"],"v":[{"t":10,"i":1,"p":{"k":["id","name"],"v":[{"t":0,"s":3},{"t":1,"s":""}],"s":2},"o":0}],"s":1},"o":0},"f":31,"m":[]}&createServerFn=
then I tried safeParse, It did display the error message, still logs the error on both client and server
const updateTodoFn = createServerFn()
.inputValidator((value) => {
const { data, error, success } = UpdateTodoIdAndName.safeParse(value);

if (!success) {
throw new Error(z.prettifyError(error));
}
return data;
})
const updateTodoFn = createServerFn()
.inputValidator((value) => {
const { data, error, success } = UpdateTodoIdAndName.safeParse(value);

if (!success) {
throw new Error(z.prettifyError(error));
}
return data;
})
then this stop logging on server
// throw new Error(z.prettifyError(error));
throw new Response(z.prettifyErr(error))
// throw new Error(z.prettifyError(error));
throw new Response(z.prettifyErr(error))
is this expected behavior? or I'm barking on the wrong tree. Sorry for my bad English

Did you find this page helpful?