React Native中查看Apollo Client GraphQL原始HTTP响应的方法
实现方案
默认配置下@apollo/client的HttpLink会在响应返回后直接执行JSON解析,一旦服务端返回HTML等非JSON内容,解析抛出的错误不会携带原始HTTP响应对象、状态码等信息,因此在onError链路中无法获取到这些内容。要拿到原始响应详情,需要通过自定义fetch拦截请求全流程,在Apollo内置解析逻辑执行前缓存原始响应信息。
步骤1:编写自定义fetch拦截逻辑
核心是在fetch拿到响应后,先读取完整的原始响应文本、记录状态码和响应头,再执行JSON解析,解析失败或HTTP状态异常时把这些原始信息挂载到错误对象上抛出,代码示例如下:
const customFetch = async (uri, options) => { // 发起原始HTTP请求 const response = await fetch(uri, options); // 提前读取原始响应文本,避免后续解析后丢失内容 const responseText = await response.text(); let parsedResponse; try { parsedResponse = JSON.parse(responseText); } catch (parseErr) { // JSON解析失败时,挂载所有原始信息到错误对象 const parseError = new Error(`JSON parse failed: ${parseErr.message}`); parseError.statusCode = response.status; parseError.rawResponse = responseText; parseError.responseHeaders = Object.fromEntries(response.headers.entries()); throw parseError; } // 处理HTTP状态非2xx的异常场景 if (!response.ok) { const httpError = new Error(`HTTP request failed with status ${response.status}`); httpError.statusCode = response.status; httpError.rawResponse = responseText; httpError.parsedResponse = parsedResponse; httpError.responseHeaders = Object.fromEntries(response.headers.entries()); throw httpError; } // 正常响应封装成标准Response对象交回Apollo处理 return new Response(JSON.stringify(parsedResponse), { status: response.status, headers: response.headers }); };
步骤2:配置HttpLink使用自定义fetch
初始化HttpLink时传入上面编写的自定义fetch,替换默认的请求逻辑:
import { createHttpLink } from '@apollo/client/link/http'; const httpLink = createHttpLink({ uri: '替换为实际的GraphQL服务端点地址', fetch: customFetch });
步骤3:在错误链路中读取原始响应信息
配置error链路时,就可以从networkError上拿到之前挂载的所有原始HTTP信息,不需要依赖模拟器的网络检查器:
import { onError } from '@apollo/client/link/error'; const errorLink = onError(({ graphQLErrors, networkError, operation }) => { if (networkError) { // 以下字段均为自定义fetch中挂载的原始信息 console.log('失败请求操作名:', operation.operationName); console.log('HTTP状态码:', networkError.statusCode); console.log('原始响应内容:', networkError.rawResponse); console.log('响应头:', networkError.responseHeaders); // 可在此处加入生产环境错误上报、容灾重试等逻辑 } if (graphQLErrors) { // 正常处理GraphQL层业务错误 graphQLErrors.forEach(err => { console.log('GraphQL业务错误:', err.message); }); } });
步骤4:组装Apollo Client实例
按顺序拼接链路,初始化客户端实例即可:
import { ApolloClient, InMemoryCache, from } from '@apollo/client'; const client = new ApolloClient({ link: from([errorLink, httpLink]), cache: new InMemoryCache() });
注意事项
- 该方案无额外第三方依赖,完全兼容Expo v44.0.6、Apollo Client v3.5.10版本,开发、生产环境均可正常生效。
- 若项目中叠加了认证、重试、文件上传等其他Apollo链路,需将
errorLink放在链路数组的最前端,保证能第一时间捕获到网络错误。 - 拿到原始响应后可针对404、502等网关返回的HTML页面做定制化处理,比如自动重试、切换备用域名等。
- 注意不要修改正常响应的返回结构,避免影响Apollo Client对合法GraphQL响应的解析和缓存逻辑。
内容的提问来源于stack exchange,提问作者user2344885
相关产品推荐
相关产品推荐

