TanStackT
TanStack12mo ago
8 replies
moderate-tomato

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 }
  })


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.")
}
Was this page helpful?