I am using tRPC
with SvelteKit for the first time, and I am stuck trying to validate the user's authentication.
I have the following in hooks.server.ts
:
import { createContext } from '$lib/trpc/context';
import { router } from '$lib/trpc/router';
import type { Handle, HandleServerError } from '@sveltejs/kit';
import { redirect } from '@sveltejs/kit';
import { createTRPCHandle } from 'trpc-sveltekit';
import { getHTTPStatusCodeFromError } from '@trpc/server/http';
const trpcHandleError = ({ type, path, error }) => {
console.error(`Encountered error while trying to process ${type} @ ${path}:`, error);
const httpStatus = getHTTPStatusCodeFromError(error);
if (httpStatus === 401) {
// How do I redirect here??
} else if (httpStatus == 403) {
// Throw a 404
}
}
export const handle: Handle = createTRPCHandle({ router, createContext, onError: trpcHandleError });
export const handleError: HandleServerError = ({ error, event }) => {
// ...or here?
}
My question is: How do I redirect the user within the trpcHandleError
to /login
if the error.code
is UNAUTHORIZED
?
I've tried simply throw redirect(307, '/login');
but it was just ignored.
onError
is a hook that gets notified when error occurs, but gives you no control over the response result.
Instead, you can provide a responseMeta
function param to createTRPCHandle({ responseMeta })
. This function is supposed to return a meta object that has { status, headers }
keys, which affects the final response (source code).
It has following function signature:
const { status, headers } = responseMeta({
ctx,
paths,
type,
data: Array<{ error: ... } | { result: { data: ... } }>,
});
You can read the params.data
array, and filter out items that have error
key to handle them. To achieve the same effect of redirect(307, '/login')
, you need to return a meta object of shape:
{ status: 307, headers: { Location: "/login" } }