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

NextJS14 + URQL全局错误处理器中页面重定向遇阻求助

解决Next.js 14 + URQL全局错误重定向问题

方案1:直接使用浏览器原生跳转(简单直接)

mapExchange的onError运行在客户端环境(URQL客户端在根布局创建,属于客户端组件),可以直接调用浏览器原生的location对象实现跳转,注意先判断当前是否处于浏览器环境:

mapExchange({
  onError(error, operation) {
    console.log(`The operation ${operation.key} has errored with:`, error);
    // 匹配你需要捕获的特定错误,比如错误信息、错误类型
    if (error.message.includes("未授权") || error.name === "AuthError") {
      if (typeof window !== 'undefined') {
        // 使用replace避免用户回退到原未授权页面
        window.location.replace("/login");
      }
    }
  },
});

方案2:结合React状态与Next.js路由(更贴合框架生态)

如果不想直接操作window,可以通过在根客户端组件中维护重定向状态,再用Next.js的useRouter实现跳转:

  1. 创建一个客户端组件包装器,维护重定向状态并暴露全局调用方法:
// app/components/AuthRedirectWrapper.tsx
'use client';

import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';

export default function AuthRedirectWrapper({ children }: { children: React.ReactNode }) {
  const [redirectPath, setRedirectPath] = useState<string | null>(null);
  const router = useRouter();

  useEffect(() => {
    if (redirectPath) {
      router.push(redirectPath);
      setRedirectPath(null);
    }
  }, [redirectPath, router]);

  // 将重定向方法挂载到window,让URQL的onError可以调用
  useEffect(() => {
    (window as any).triggerAuthRedirect = (path: string) => {
      setRedirectPath(path);
    };
    return () => {
      delete (window as any).triggerAuthRedirect;
    };
  }, []);

  return children;
}
  1. 在根布局中引入这个包装器:
// app/layout.tsx
import AuthRedirectWrapper from './components/AuthRedirectWrapper';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="zh-CN">
      <body>
        <AuthRedirectWrapper>{children}</AuthRedirectWrapper>
      </body>
    </html>
  );
}
  1. 在URQL的mapExchange中调用全局重定向方法:
mapExchange({
  onError(error, operation) {
    console.log(`The operation ${operation.key} has errored with:`, error);
    if (error.message.includes("未授权") || error.name === "AuthError") {
      if (typeof window !== 'undefined' && (window as any).triggerAuthRedirect) {
        (window as any).triggerAuthRedirect("/login");
      }
    }
  },
});

关于之前方法失效的原因

  • useRouter是React Hook,必须在组件或自定义Hook的顶层调用,无法在普通函数(比如onError)中直接使用。
  • next/navigation的redirect函数仅适用于服务器组件,在客户端组件中调用会抛出NEXT_REDIRECT错误,因为它是为服务器端跳转逻辑设计的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 10:57:18