能否将Apollo Client的GraphQL服务端错误传递至客户端?
解决Apollo Client服务端能捕获GraphQL错误但客户端error为undefined的问题
核心原因
Apollo Client的错误策略(errorPolicy) 默认配置可能导致GraphQL错误不会被挂载到useQuery返回的error对象上:
- 若设置为
ignore:即使服务端返回GraphQL错误,客户端会忽略错误并返回数据,error为undefined - 若设置为
none:只要有GraphQL错误,整个请求会被视为失败,error会包含完整错误信息 - 若设置为
all:会同时返回数据和错误,error对象会包含graphQLErrors
解决方法
1. 调整错误策略(全局/单个查询)
全局配置(所有查询生效)
创建Apollo Client实例时,设置全局默认错误策略:
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client'; const client = new ApolloClient({ uri: '/your-graphql-endpoint', cache: new InMemoryCache(), link: new HttpLink({ uri: '/your-graphql-endpoint' }), defaultOptions: { query: { errorPolicy: 'all', // 可选值:'all'/'none'/'ignore',按需选择 }, }, });
单个查询配置(覆盖全局)
在useQuery调用中单独指定错误策略:
import { useQuery } from '@apollo/client'; import YOUR_QUERY from './queries/YourQuery'; const { data, loading, error } = useQuery(YOUR_QUERY, { errorPolicy: 'all', // 确保GraphQL错误被捕获到error对象中 }); // 此时可访问error?.graphQLErrors if (error) { console.log('GraphQL Errors:', error.graphQLErrors); }
2. 全局错误捕获(Apollo Link)
通过onError Link在请求链路中全局捕获GraphQL错误,确保错误能传递到客户端:
import { ApolloClient, InMemoryCache, ApolloLink, from } from '@apollo/client'; import { onError } from '@apollo/client/link/error'; import { HttpLink } from '@apollo/client'; const errorLink = onError(({ graphQLErrors, networkError }) => { if (graphQLErrors) { // 可在这里处理错误(如上报、存储到状态管理) graphQLErrors.forEach(err => { console.log(`GraphQL Error: ${err.message}`); }); } if (networkError) { console.log(`Network Error: ${networkError.message}`); } }); const httpLink = new HttpLink({ uri: '/your-graphql-endpoint' }); const client = new ApolloClient({ cache: new InMemoryCache(), link: from([errorLink, httpLink]), });
3. SSR场景下传递错误到客户端
如果是服务端渲染(如Next.js),可在服务端请求阶段捕获错误,直接传递给客户端组件:
// 页面的getServerSideProps import { initializeApollo } from '../apollo/client'; import YOUR_QUERY from './queries/YourQuery'; export async function getServerSideProps() { const apolloClient = initializeApollo(); let serverError = null; try { await apolloClient.query({ query: YOUR_QUERY }); } catch (err) { // 服务端捕获GraphQL错误 serverError = err.graphQLErrors; } return { props: { initialApolloState: apolloClient.cache.extract(), serverError, // 将错误传递给客户端组件 }, }; } // 客户端页面组件 export default function YourPage({ serverError }) { // 渲染前处理服务端传递的错误 if (serverError) { return <div className="error">请求出错:{serverError[0].message}</div>; } const { data, loading } = useQuery(YOUR_QUERY); if (loading) return <div>加载中...</div>; return <div>{/* 渲染数据 */}</div>; }
内容的提问来源于stack exchange,提问作者meez
相关产品推荐
相关产品推荐

