T
TanStack11mo ago
harsh-harlequin

Throwing errors with non-500 status from server functions

Hiya, great work on Tanstack Start and Router, really enjoying using it! Except for this tiny nitpick: If I understand the docs (https://tanstack.com/router/latest/docs/framework/react/start/server-functions#throwing-errors) correctly, you can only throw errors with HTTP status code 500. I'm just starting to build my new app with Tanstack Start, and I'm implementing auth first. It is fully functional; I validate with Zod (password.length > 8 etc.), and I throw an error if the username and password don't match. This means that my server responds with HTTP 500 in these cases, which is of course not the really correct status code. Is there a way to throw errors with custom status codes (400 and 401 in this case)? I tried returning a custom Response instead of throwing errors, but that messes up the return type of the action. Or am I just totally misunderstanding how I should go about implementing a login server function? This is my simplified function:
export const login = createServerFn({ method: 'POST' })
.validator(loginSchema)
.handler(async ({ data ) => {
const user = await getUserFromEmail(data.email)
if (!user || !user.passwordHash) {
throw new Error("Incorrect username or password.")
}

const passwordMatch = await argon2.verify(user.passwordHash, data.password)
if (!passwordMatch) {
throw new Error("Incorrect username or password.")
}

const session = await createSession(user.id)
return { session }
})
export const login = createServerFn({ method: 'POST' })
.validator(loginSchema)
.handler(async ({ data ) => {
const user = await getUserFromEmail(data.email)
if (!user || !user.passwordHash) {
throw new Error("Incorrect username or password.")
}

const passwordMatch = await argon2.verify(user.passwordHash, data.password)
if (!passwordMatch) {
throw new Error("Incorrect username or password.")
}

const session = await createSession(user.id)
return { session }
})
Ideally, I think I would like to be able to do this: (also from the validator!)
if (!passwordMatch) {
setResponseStatus(401)
throw new Error("Incorrect username or password.")
}
if (!passwordMatch) {
setResponseStatus(401)
throw new Error("Incorrect username or password.")
}
7 Replies
continuing-cyan
continuing-cyan11mo ago
Ah I thought I found something but testing in practice didn't work cc @Manuel Schiller
rival-black
rival-black11mo ago
hm?
continuing-cyan
continuing-cyan11mo ago
any way to do this currently?
rival-black
rival-black11mo ago
no
rival-black
rival-black11mo ago
add a github issue if you think this is a feature you need
rare-sapphire
rare-sapphire10mo ago
https://github.com/TanStack/router/discussions/2887 yall should upvote this cc @Ryan Gillie @Quinten
GitHub
[Start]: Throwing errors with a status code · TanStack router · Dis...
Would it be possible to throw errors in server functions / middlewares along with a custom status code instead of systematically respond with a 500 code. For clarity and documentation, always retur...

Did you find this page helpful?