当GraphQL API不可用时通过Apollo重定向至错误页面的实现方法
嘿,这个需求其实挺常见的,咱们可以通过Apollo Client的错误拦截机制来实现,我给你拆解几种实用的实现方式:
核心思路:拦截Apollo的错误响应
Apollo Client允许我们通过**错误链接(Error Link)**全局捕获所有请求错误,或者在单个查询/突变里单独处理错误。只需要判断错误的状态码是否为503,再触发重定向即可。
1. 全局处理(推荐):用onError Link捕获所有503错误
这种方式会对所有GraphQL请求生效,一次配置全项目通用,非常省心。
import { ApolloClient, InMemoryCache, createHttpLink, from } from '@apollo/client'; import { onError } from '@apollo/client/link/error'; // 创建指向你的GraphQL API的HTTP链接 const httpLink = createHttpLink({ uri: '/your-graphql-endpoint', // 替换成你的API地址 }); // 配置错误处理逻辑 const errorLink = onError(({ networkError }) => { // 检查是否是503服务不可用错误 if (networkError?.statusCode === 503) { // 重定向到你的错误页面,这里用原生window.location跳转 window.location.href = '/error-service-unavailable'; // 如果用React Router v6+,可以提前把history对象传入(注意:初始化Client时不能直接用useNavigate钩子) // 比如可以创建一个history实例,在这里调用history.push('/error-service-unavailable') } }); // 组合错误链接和HTTP链接,创建Apollo Client实例 const client = new ApolloClient({ link: from([errorLink, httpLink]), // 错误链接要放在HTTP链接前面,才能拦截错误 cache: new InMemoryCache(), });
补充说明:
- 用
?.可选链操作符是为了避免某些异常场景下(比如跨域错误)networkError不存在导致的报错。 - 如果需要给错误页面传递额外信息,可以在重定向URL里加参数:
window.location.href = '/error?code=503&msg=服务暂时不可用',然后在错误页面解析这些参数展示。
2. 局部处理:针对特定查询/突变处理503错误
如果只需要在某个特定请求中处理503错误,可以直接在组件的useQuery或useMutation里配置onError回调:
import { useQuery, gql } from '@apollo/client'; import { useNavigate } from 'react-router-dom'; // 定义你的GraphQL查询 const FETCH_DATA = gql` query FetchData { // 你的查询字段 } `; function YourComponent() { const navigate = useNavigate(); const { loading, error, data } = useQuery(FETCH_DATA, { onError: (err) => { // 捕获当前查询的503错误并跳转 if (err.networkError?.statusCode === 503) { navigate('/error-service-unavailable'); } }, }); // 处理其他加载/错误状态 if (loading) return <p>加载中...</p>; if (error && error.networkError?.statusCode !== 503) { return <p>加载失败,请稍后重试</p>; } return <div>{/* 渲染你的数据内容 */}</div>; }
补充说明:
这种方式适合只需要在特定页面/请求中处理503的场景,用React Router的useNavigate钩子跳转比原生window.location更符合单页应用的路由逻辑。
3. 兼容Apollo Client v2的写法
如果你还在使用Apollo Client v2,onError链接需要从apollo-link-error包导入,代码结构大同小异:
import { ApolloClient, InMemoryCache, HttpLink } from 'apollo-client-preset'; import { onError } from 'apollo-link-error'; import { ApolloLink } from 'apollo-link'; const httpLink = new HttpLink({ uri: '/your-graphql-endpoint' }); const errorLink = onError(({ networkError }) => { if (networkError?.statusCode === 503) { window.location.href = '/error-service-unavailable'; } }); const client = new ApolloClient({ link: ApolloLink.from([errorLink, httpLink]), cache: new InMemoryCache(), });
内容的提问来源于stack exchange,提问作者user7770410
相关产品推荐
相关产品推荐

