使用@apollo/client如何在React组件/自定义Hook获取详细GraphQL错误
Apollo Client组件中获取GraphQL详细错误的解决方法
问题场景
我正在使用@apollo/client,整体功能运行正常。在index.ts中通过以下代码可以打印出GraphQL的具体错误:
const errorLink = onError(({ graphQLErrors, networkError }) => { if (graphQLErrors) { graphQLErrors.map(({ message, extensions }) => { console.log(`[GraphQL错误]: 消息: ${message}, 错误码: ${extensions.code}`); }); } if (networkError) { // 处理网络错误 console.log(networkError); } });
但在组件的自定义Hook中调用查询时,只能拿到模糊的错误提示:
Response not successful: Received status code 400
我需要获取到像index.ts中那样的详细错误信息,比如:
[GraphQL错误]: 消息: 变量 "$input" 收到无效值 { country: "deu" }; 必填字段 "accountProduct"(类型为"String!")未提供。, 错误码: BAD_USER_INPUT
我的自定义Hook代码如下:
const { loading: letLoading, error: letError, data: letData } = useQuery(fetchTypes, { variables: { input: { country: 'deu' }, errorPolicy: "all" }, }); function fetchLETService() { setLetStatus({ letLoading }); if (letError) { console.log(letError) } if (letData) { setLetStatus({ letLoading: false, letData: letData.types }); } }
问题原因
errorPolicy的配置位置错误,当前它被嵌套在variables对象中,导致Apollo Client无法正确识别并应用该策略,因此组件仅能捕获HTTP层面的状态码错误,无法获取GraphQL返回的详细错误信息。
修复方案
1. 修正errorPolicy的配置位置
将errorPolicy从variables对象中移出,作为useQuery的顶层配置参数:
const { loading: letLoading, error: letError, data: letData } = useQuery(fetchTypes, { variables: { input: { country: 'deu' } }, errorPolicy: "all" // 移至顶层配置 });
2. 访问详细的GraphQL错误信息
当errorPolicy设置为"all"时,letError对象会包含graphQLErrors数组,你可以通过遍历该数组获取每条错误的详细内容:
function fetchLETService() { setLetStatus({ letLoading }); if (letError) { // 处理GraphQL错误 if (letError.graphQLErrors) { letError.graphQLErrors.forEach(({ message, extensions }) => { console.log(`[GraphQL错误]: 消息: ${message}, 错误码: ${extensions.code}`); }); } // 处理网络错误 if (letError.networkError) { console.log('网络错误:', letError.networkError); } } if (letData) { setLetStatus({ letLoading: false, letData: letData.types }); } }
关于errorPolicy的补充说明
Apollo Client提供三种错误策略可选:
"none"(默认):仅返回网络错误,GraphQL错误会被忽略且不存入缓存"ignore":GraphQL错误不会触发组件的error状态,但会存入缓存"all":同时返回网络错误和GraphQL错误,且GraphQL错误会存入缓存
内容的提问来源于stack exchange,提问作者Siddharth Mishra
相关产品推荐
相关产品推荐

