Apollo Client ErrorLink 完全指南:基于 `@apollo/client/link/error` 的 GraphQL 错误处理实战

发布时间:2026/9/20 22:21:53

Apollo Client ErrorLink 完全指南:基于 `@apollo/client/link/error` 的 GraphQL 错误处理实战 Apollo Client ErrorLink 完全指南基于apollo/client/link/error的 GraphQL 错误处理实战【免费下载链接】apollo-clientThe industry-leading GraphQL client for TypeScript, JavaScript, React, Vue, Angular, and more. Apollo Client delivers powerful caching, intuitive APIs, and comprehensive developer tools to accelerate your app development.项目地址: https://gitcode.com/gh_mirrors/ap/apollo-client本篇技术指南围绕仓库公开 API 报告 .api-reports/api-report-link_error.api.md 所声明的apollo/client/link/error模块展开系统讲解 Apollo Client 官方推荐的ErrorLink类及其配套类型ErrorHandler、ErrorHandlerOptions并深入源码 src/link/error/index.ts 与测试 src/link/error/tests/index.ts说明其触发时机、错误分类、重试与忽略机制。读完本文你将能够用ErrorLink统一捕获 GraphQL 错误、协议错误与网络错误实现日志、上报、重试与错误静默等常见需求。ErrorLink 是什么面向响应的错误处理链在 Apollo Client 的 link 链中请求从上游流向终止 link如 HttpLink而响应则沿链路反向回传。ErrorLink是一个特殊的 link它不拦截请求本身而是在GraphQL 操作执行完毕、结果沿链路回传时触发你注册的errorHandler回调用于检查并处理出现的错误。因此它非常适合放在所有终止 link 之前即concat链的靠前位置这样任何下游 linkHTTP、WS、批处理等产生的错误都能被它观察到。该模块的公开 API 由 API Extractor 报告完整定义为以下三部分见 .api-reports/api-report-link_error.api.md// public (undocumented) export namespace ErrorLink { export interface ErrorHandler { (options: ErrorHandlerOptions): ObservableApolloLink.Result | void; } export interface ErrorHandlerOptions { error: ErrorLike; forward: ApolloLink.ForwardFunction; operation: ApolloLink.Operation; result?: ApolloLink.Result; } export namespace ErrorLinkDocumentationTypes { ... } } // public export class ErrorLink extends ApolloLink { constructor(errorHandler: ErrorLink.ErrorHandler); } // public deprecated (undocumented) export function onError(errorHandler: ErrorLink.ErrorHandler): ErrorLink;其中ErrorLink是推荐使用的类onError是旧版本遗留的工厂函数已被标记为deprecated详见下文迁移说明。快速上手接入 ErrorLink模块入口在apollo/client/link/error对应源码文件为 src/link/error/index.ts。引入方式import { ErrorLink } from apollo/client/link/error; import { ApolloLink } from apollo/client/link; const errorLink new ErrorLink(({ operation, error }) { // 在这里统一处理三类错误GraphQL 错误、协议错误、网络错误 console.error(${operation.operationName} 执行失败:, error); }); const client new ApolloClient({ link: ApolloLink.from([errorLink, httpLink]), cache: new InMemoryCache(), });构造函数签名如下与 API 报告一致constructor(errorHandler: ErrorLink.ErrorHandler): ErrorLinkerrorHandler的唯一约束是回调的返回值要么是void仅观察、不干预要么是一个ObservableApolloLink.Result用于重试操作。测试 src/link/error/tests/index.ts 中大量使用了new ErrorLink(callback)jest.fn()的断言方式验证回调入参。ErrorHandlerOptions 详解回调能拿到什么ErrorHandler回调的唯一入参是一个ErrorHandlerOptions对象包含四个字段语义均可在 src/link/error/index.ts 的类型注释中找到字段类型说明errorErrorLike本次触发的错误对象。可能是CombinedGraphQLErrorsGraphQL 错误、CombinedProtocolErrors传输层协议错误或其他网络错误类型需要用各自的is()方法判别result?ApolloLink.Result服务器返回的原始 GraphQL 结果若可得可能包含部分数据data连同错误operationApolloLink.Operation产生错误的 GraphQL 操作详情含query、operationName、variables等forwardApolloLink.ForwardFunction指向 link 链中下一个 link 的函数。只有想重试操作时才需要调用forward(operation)它会返回一个新的 Observable 供上游订阅一个典型的日志用例源码 src/link/error/index.ts 的example代码块直接可运行import { ErrorLink } from apollo/client/link/error; import { CombinedGraphQLErrors, CombinedProtocolErrors, } from apollo/client/errors; const errorLink new ErrorLink(({ error, operation }) { if (CombinedGraphQLErrors.is(error)) { error.errors.forEach(({ message, locations, path }) console.log( [GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path} ) ); } else if (CombinedProtocolErrors.is(error)) { error.errors.forEach(({ message, extensions }) console.log( [Protocol error]: Message: ${message}, Extensions: ${JSON.stringify( extensions )} ) ); } else { console.error([Network error]: ${error}); } });触发时机与三类错误判别从 src/link/error/index.ts 的实现可见ErrorLink是在forward(operation)返回的 Observable 上订阅并按以下优先级判定GraphQL 错误result.errors非空将error包装为new CombinedGraphQLErrors(result, errors)传给回调。CombinedGraphQLErrors定义于 src/errors/CombinedGraphQLErrors.ts实例携带errors原始错误数组、data部分数据与extensions属性默认把各条message用换行符拼接为message。协议错误extensions[PROTOCOL_ERRORS_SYMBOL]存在对于 multipart 订阅等场景传输层错误被存放于extensions的私有 Symbol 键上见 src/errors/index.ts 中的PROTOCOL_ERRORS_SYMBOL与graphQLResultHasProtocolErrors此时error为CombinedProtocolErrors实例定义见 src/errors/CombinedProtocolErrors.ts。这类错误表示订阅传输本身的问题而非业务 GraphQL 错误。网络/其他错误Observableerror事件或同步抛出错误会经toErrorLike规范化。toErrorLikesrc/errors/index.ts的规则是已是ErrorLike则原样返回字符串包装为Error其他非常规类型Symbol、普通对象、数组等包装为UnconventionalError。测试中的 wraps strings emitted from terminating link in Error 与 wraps unconventional error types in UnconventionalError 用例即验证了这一点。因此error字段的类型判别建议如下if (CombinedGraphQLErrors.is(error)) { // 服务端返回的 errors 数组可读取 error.errors / error.data / error.extensions } else if (CombinedProtocolErrors.is(error)) { // multipart 订阅的传输层协议错误可读取 error.errors } else { // 网络错误如 ServerError携带 statusCode或其他异常 }值得一提的是error判别函数都是基于品牌标记的类型守卫isBranded用于让 TypeScript 在分支内自动收窄类型。此外仓库还提供LinkError工具src/errors/LinkError.ts它不是错误类而是记录错误是否来自 link 链的注册表可在调用方用于区分链路错误与业务代码自抛错误。自定义错误消息格式CombinedGraphQLErrors与CombinedProtocolErrors都暴露了静态的formatMessage属性可通过覆盖它来改变error.message的拼装方式需在首次执行任何操作前配置。例如用逗号连接各条消息import { CombinedGraphQLErrors } from apollo/client/errors; CombinedGraphQLErrors.formatMessage (errors) { return errors.map((error) error.message).join(, ); };重试操作返回 Observable 的进阶用法errorHandler返回ObservableApolloLink.Result时ErrorLink会转而订阅该 Observable 并将其结果转发给上游从而实现链路级重试。这是重新执行整个操作的标准姿势与用重试函数延迟重新发起请求如 retry link 中的延迟策略不同重试的是同一次操作在新 Observable 上的完整执行。import { ErrorLink } from apollo/client/link/error; import { Observable } from rxjs; const errorLink new ErrorLink(({ operation, forward, error }) { // 只对网络错误重试一次 if (error instanceof ServerError error.statusCode 500) { return forward(operation); // 重新执行操作返回新的 Observable } // 其他情况返回 void错误继续沿原路径传播 });实现细节src/link/error/index.ts回调返回 Observable 后ErrorLink会调用retriedResult?.subscribe(observer)订阅它若回调返回void则把原始result用observer.next(result)透传、把原始错误用observer.error(error)继续抛出从而不改变原有行为当重试正在进行时complete事件会被抑制if (!retriedResult)才调用observer.complete()避免重试结果未到达就提前结束取消订阅时原始订阅与重试订阅都会执行unsubscribe()防止资源泄漏。忽略与修改错误静默处理不需要的场景如果只是想让某些错误消失可以在回调中直接修改result后再返回void。测试 src/link/error/tests/index.ts 的 allows an error to be ignored 用例展示了这一用法const errorLink new ErrorLink(({ result }) { if (isFormattedExecutionResult(result)) { delete result!.errors; // 删除 errors 字段后结果被视为成功 } });删除errors后下游与调用方将不再感知到该错误。这种模式适用于部分成功可接受或错误由别的通道上报的场景。从 onError 迁移到 ErrorLinkonError函数在当前仓库中被明确标记为deprecated其实现只有一行src/link/error/index.tsexport function onError(errorHandler: ErrorLink.ErrorHandler) { return new ErrorLink(errorHandler); }迁移方式非常简单onError(fn)等价于new ErrorLink(fn)回调签名完全一致直接替换构造方式即可// 旧写法已弃用 import { onError } from apollo/client/link/error; const link onError(handler); // 新写法推荐 import { ErrorLink } from apollo/client/link/error; const link new ErrorLink(handler);增量响应defer / multipart中的错误处理ErrorLink同样覆盖增量执行协议下的错误场景。在 src/link/error/index.ts 的next处理器中错误提取逻辑会优先询问operation.client[queryManager].incrementalHandlerconst handler operation.client[queryManager].incrementalHandler; const errors handler.isIncrementalResult(result) ? handler.extractErrors(result) : result.errors;也就是说当结果被判定为增量结果如defer的后续 chunk、GraphQL 17 alpha 增量响应时错误从增量块中提取并同样包装为CombinedGraphQLErrors普通结果则读取顶层errors字段。对应的测试用例Defer20220824Handler、GraphQL17Alpha9Handler分别验证了增量块errors与completed块中的错误都能正确触发回调相关 handler 实现见 src/incremental/handlers。测试验证与行为保证src/link/error/tests/index.ts 是ErrorLink行为的事实来源它覆盖了以下关键保证GraphQL 错误触发回调result.errors存在时回调恰好调用一次入参含forward、operation、result与CombinedGraphQLErrors包装的error同步抛出与 Observable error 均能捕获下游 link 抛错、observer.error(error)、subscribe内抛错三种路径都会被捕获非常规错误类型规范化字符串被包为ErrorSymbol/对象/数组被包为UnconventionalError无错误不打扰正常数据流不会触发回调流正常完成可取消unsubscribe后回调不再触发订阅被正确清理保留上下文operation.getContext()中的自定义上下文在回调中可读。相关资源模块 API 报告.api-reports/api-report-link_error.api.md实现源码src/link/error/index.ts行为测试src/link/error/tests/index.ts官方 API 文档由该模块生成docs/source/api/link/apollo-link-error.mdx错误处理完整指南docs/source/data/error-handling.mdx配套错误类型CombinedGraphQLErrorssrc/errors/CombinedGraphQLErrors.ts、CombinedProtocolErrorssrc/errors/CombinedProtocolErrors.ts、错误模块导出src/errors/index.ts【免费下载链接】apollo-clientThe industry-leading GraphQL client for TypeScript, JavaScript, React, Vue, Angular, and more. Apollo Client delivers powerful caching, intuitive APIs, and comprehensive developer tools to accelerate your app development.项目地址: https://gitcode.com/gh_mirrors/ap/apollo-client创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/20 23:17:20

腾讯云FDE认证:部署交付工程师的标准化之路

腾讯云最近放出了一个新消息,行业里第一个FDE工程师认证正式上线,FDE合作伙伴招募也同步启动了。FDE这个名字,第一次听的人可能会心里嘀咕,这跟平时念叨的IDE、CDN,还有各种"XXX认证"到底有什么关系。简单说…

2026/9/20 23:17:20

SpringBoot+Vue代驾管理系统架构与智能派单实现

1. 项目背景与核心价值辽B代驾管理系统是一套面向代驾服务企业的全流程信息化解决方案。这个系统最吸引人的地方在于它采用了当前企业级开发中最主流的SpringBootVue前后端分离架构,并且提供了开箱即用的完整源码包。对于中小型代驾公司来说,这种"拿…

2026/9/20 0:04:49

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/20 0:04:49

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/20 0:04:49

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/20 0:04:49

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/20 4:54:47

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/20 5:01:23

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/20 5:09:33

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码