You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SvelteKit的tRPC错误处理中实现页面重定向?

解决tRPC + SvelteKit中401未授权重定向问题

直接在tRPC的onError回调中throw redirect()无效的原因是:该回调属于tRPC内部错误处理流程,抛出的错误会被tRPC捕获并转化为HTTP响应,无法触发SvelteKit的重定向逻辑。以下是两种可行的解决方案:

方案一:在createContext阶段提前校验身份(推荐)

在创建tRPC上下文时就完成用户身份校验,未认证直接抛出重定向,避免进入路由处理环节,更高效:

// $lib/trpc/context.ts
import { redirect } from '@sveltejs/kit';
import type { RequestEvent } from '@sveltejs/kit';

export async function createContext(event: RequestEvent) {
  // 替换为你的实际身份校验逻辑(比如从Cookie/Session获取用户)
  const user = await fetchCurrentUserFromSession(event);

  if (!user) {
    // 未认证直接触发重定向
    throw redirect(307, '/login');
  }

  return {
    user,
    event // 将event存入上下文,方便后续使用
  };
}

方案二:在tRPC onError中修改响应实现重定向

如果需要针对特定路由的UNAUTHORIZED错误处理(比如部分路由允许匿名访问),可以通过上下文传递SvelteKit的event对象,直接修改响应头实现重定向:

修改hooks.server.ts:

import { createContext } from '$lib/trpc/context';
import { router } from '$lib/trpc/router';
import type { Handle } from '@sveltejs/kit';
import { createTRPCHandle } from 'trpc-sveltekit';
import { getHTTPStatusCodeFromError } from '@trpc/server/http';
import type { TRPCError } from '@trpc/server';

const trpcHandleError = ({ error, ctx }) => {
  console.error(`tRPC error [${error.code}] @ ${error.path}:`, error.message);
  const httpStatus = getHTTPStatusCodeFromError(error as TRPCError);
  const event = ctx?.event;

  if (httpStatus === 401 && event) {
    // 直接设置重定向响应
    event.response = new Response(null, {
      status: 307,
      headers: { Location: '/login' }
    });
  } else if (httpStatus === 403 && event) {
    // 返回404响应
    event.response = new Response('Not Found', { status: 404 });
  }
};

export const handle: Handle = async ({ event, resolve }) => {
  // 调用tRPC处理函数,并传入event到context
  const trpcResult = await createTRPCHandle({
    router,
    createContext: () => createContext(event),
    onError: trpcHandleError
  })({ event, resolve });

  // 如果tRPC已生成响应,直接返回
  if (trpcResult) return trpcResult;

  // 处理非tRPC请求
  return resolve(event);
};

补充:客户端调用的错误处理

如果是在Svelte组件中调用tRPC客户端,需要在客户端错误回调中处理重定向:

// $lib/trpc/client.ts
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
import type { Router } from '$lib/trpc/router';
import { goto } from '$app/navigation';

export const trpc = createTRPCProxyClient<Router>({
  links: [
    httpBatchLink({ url: '/api/trpc' })
  ],
  onError: (error) => {
    if (error.data?.httpStatus === 401) {
      goto('/login');
    }
  }
});

内容的提问来源于stack exchange,提问作者Basil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 01:10:27