Graffle 输出配置实战:使用 errorChannel 让 GraphQL 错误以返回值代替异常抛出
后端【免费下载链接】graffleSimple GraphQL Client for JavaScript. Minimal. Extensible. Type Safe. Runs everywhere.项目地址https://gitcode.com/gh_mirrors/gr/graffle点击查看免费下载导读Graffle 是一个极简、可扩展且类型安全的 JavaScript GraphQL 客户端。默认情况下Graffle 会把 GraphQL 执行错误与扩展层错误统一以异常throw的形式抛出而在很多业务场景中开发者更希望错误像普通返回值一样参与流程控制。本文围绕 Graffle 官方示例 return-error 展开讲解如何通过output.defaults.errorChannel: return将错误改为返回并深入output.errors细粒度配置、类型系统如何同步收窄返回值以及源码层面的错误分发原理帮助你写出更可控的错误处理代码。默认行为错误一律抛出在了解return之前先明确 Graffle 的默认输出行为。直接调用Graffle.create()而不传任何配置时客户端会使用默认输出设置const pokemon Graffle.create() const pokemons await pokemon.query.pokemons({ name: true })对应官方示例 default 及 examples/20_output/output_default.ts。此时若请求出现错误例如发送空查询、执行错误或扩展抛错请求会以异常形式结束。这一默认行为在源码配置中有明确体现在 output 配置片段 中defaults.errorChannel的默认值为throwconst default_ { defaults: { errorChannel: throw, }, ... }同时测试 with_output.test.ts 也用内联快照验证了默认抛错行为test(default is throws errors, async () { await expect(g1.gql().$send()).rejects.toThrowErrorMatchingInlineSnapshot( [ContextualAggregateError], ) })核心配置output.defaults.errorChannel: return要让错误从抛出变为返回只需在创建客户端时配置output.defaults.errorChannel。官方示例 return-error 给出的完整代码如下import { Graffle } from ./graffle/_.js const pokemon Graffle .create({ output: { envelope: false, defaults: { errorChannel: return, }, }, }) .anyware(({ encode: _ }) { throw new Error(Something went wrong.) }) const pokemons await pokemon.query.pokemons({ name: true }) console.log(pokemons)该示例对应的可运行源码位于 examples/20_output/output_return-error.ts。可以看到示例通过.anyware()在encode钩子中主动抛出一个错误用于模拟其他类错误other error例如扩展抛出的错误、传输层网络错误等。关键点在于即使拦截器内部throw了错误配置了errorChannel: return之后pokemon.query.pokemons(...)调用不会抛出异常而是把错误作为函数的返回值交还给调用方随后console.log(pokemons)正常打印出错误对象。示例运行后的实际输出来源 output_return-error.snapContextualError: There was an error in the interceptor anonymous (use named functions to improve this error message) while running hook encode. at runPipeline (/some/path/to/runPipeline.ts:XX:XX) at async anonymous (/some/path/to/runner.ts:XX:XX) at async Module.run (/some/path/to/run.ts:XX:XX) at async sendRequest (/some/path/to/send.ts:XX:XX) at async executeRootField (/some/path/to/requestMethods.ts:XX:XX) at async anonymous (/some/path/to/output_return-error.ts:XX:XX) { context: { hookName: encode, source: extension, interceptorName: anonymous }, cause: Error: Something went wrong. at anonymous (/some/path/to/output_return-error.ts:XX:XX) at applyBody (/some/path/to/runner.ts:XX:XX) }这个返回的错误是ContextualError类型它携带了非常丰富的诊断信息context字段记录了hookName: encode、source: extension与interceptorName说明错误发生在请求管线的哪个环节cause字段保留了原始的Error: Something went wrong.不丢失根因错误消息提示use named functions to improve this error message——若希望错误信息更友好可以给拦截器命名函数而不是匿名函数。配置项全解output片段支持哪些参数结合 configuration.ts 中的Input接口output配置完整支持以下参数配置路径类型默认值说明output.defaults.errorChannelthrow \| returnthrow全局默认错误通道抛出或返回output.envelopeboolean \| { enabled?, errors?: { execution?, other? } }false是否启用信封输出data/errors/extensions结构output.errors.executionthrow \| return \| defaultdefault执行错误的通道default表示跟随defaults.errorChanneloutput.errors.otherthrow \| return \| defaultdefault其他错误网络、扩展等的通道default表示跟随defaults.errorChannel其中两类错误的官方定义源码注释为execution 错误传统上出现在 GraphQL 执行结果errors字段中的错误例如字段校验失败、参数不合法等other 错误包括 HTTP 传输时fetch抛出的网络错误、扩展extension抛出的错误等。default的解析逻辑由readErrorCategoryOutputChannel实现configuration.tsexport const readErrorCategoryOutputChannel ( output: Normalized, errorCategory: ErrorCategory, ): OutputChannel | false { if (output.errors[errorCategory] default) { return output.defaults.errorChannel } return output.errors[errorCategory] }也就是说errors.execution与errors.other的default取值会在运行时被解析为defaults.errorChannel的实际值。这正是全局默认 按类覆盖两级配置模型的实现基础。类型系统同步返回值类型自动包含错误联合errorChannel: return的另一个优势在于类型层面的一致性。在 handle.ts 的类型定义中IfConfiguredGetOutputErrorReturns会根据配置把错误类型并入返回类型type IfConfiguredGetOutputErrorReturns$OutputConfig extends Normalized | (ConfigGetOutputError$OutputConfig, execution extends return ? GraphqlKit.Request.GraphQLExecutionResultError : never) | (ConfigGetOutputError$OutputConfig, other extends return ? Ware.ResultFailure : never)这意味着启用errorChannel: return后await pokemon.query.pokemons(...)的静态类型会自动变为正常数据 | 执行错误 | 其他错误的联合类型。TypeScript 编译器会强制你处理错误分支从源头杜绝忘记 catch的问题。注释掉的测试用例也印证了这一点with_output.test.ts// const g G({ output: { defaults: { errorChannel: return } }, checkPreflight: false }) // test(query.fieldMethod, async () { // expectTypeOf(await g.query.__typename()).toEqualTypeOf // Query | Ware.ResultFailure | GraphQLExecutionResultError // () // })细粒度控制errors.execution与errors.other分开配置如果业务上希望执行错误返回、其他错误抛出或反之可以使用errors参数覆盖默认通道。官方姊妹示例 return-error-execution 及其源码 output_return-error_return-error-execution__return-error-execution.ts 展示了这种场景const pokemon Graffle .create({ output: { envelope: false, errors: { execution: return, other: throw, }, }, }) // 1. 执行错误空的 Pokemon name会被返回 const result await pokemon.mutation.addPokemon({ $: { name: , hp: 1, defense: 0, attack: 0, $type: water }, name: true, }) console.log(result) // 2. 其他错误此处来自内联扩展会被抛出 try { await pokemon .anyware(({ encode: _ }) { throw new Error(Something went wrong.) }) .query .pokemons({ name: true }) } catch (error) { console.log(error) }在该示例中addPokemon因为空名称触发的执行错误ContextualAggregateError包含too_small、Pokemon name cannot be empty.等结构化信息会被返回而.anyware()内联扩展抛出的错误则依旧抛出。这样就能针对不同错误来源制定不同的处理策略。测试 with_output.test.ts 也覆盖了这种组合配置的类型推导// .execution: throw // expectTypeOf(await g.query.__typename()).toEqualTypeOfQuery | Ware.ResultFailure() // .other: throw // expectTypeOf(await g.query.__typename()).toEqualTypeOfQuery | GraphQLExecutionResultError()即把某类错误设为throw后该类错误会从返回类型联合中消失类型层面与运行时行为保持同步。底层原理handleOutput如何分发错误errorChannel的运行时语义最终由 handle.ts 中的handleOutput函数实现。它会读取规范化后的输出配置逐类判断错误的处理方式const isThrowOther readErrorCategoryOutputChannel(c, other) throw (!c.envelope.enabled || !c.envelope.errors.other) const isReturnOther readErrorCategoryOutputChannel(c, other) return (!c.envelope.enabled || !c.envelope.errors.other) const isThrowExecution readErrorCategoryOutputChannel(c, execution) throw (!c.envelope.enabled || !c.envelope.errors.execution) const isReturnExecution readErrorCategoryOutputChannel(c, execution) return (!c.envelope.enabled || !c.envelope.errors.execution)随后针对两类错误分别处理当管线输出是Error实例即 other 类错误如拦截器抛错时isThrowOther则throw resultisReturnOther则return result当执行结果result.value.errors非空execution 类错误时先包装成Err.ContextualAggregateError再依据isThrowExecution/isReturnExecution决定抛出或返回正常数据则返回result.value.data未启用信封时或完整的执行结果信封。从这段实现可以推断errorChannel与envelope信封输出是互相影响的两个维度——当信封启用且对应错误类别被收进信封时错误会放入信封的errors字段而非直接返回/抛出。配置默认值中envelope.enabled为false、errors.execution/other均为default因此开箱即用行为是执行错误与其他错误全部跟随defaults.errorChannel。实战建议与注意事项优先使用命名拦截器匿名拦截器抛错时返回的ContextualError消息会提示use named functions to improve this error message。为.anyware()的拦截器命名可让诊断信息更可读。结合envelope使用若同时开启output.envelope: true且希望错误进入信封可参考 envelope 示例并通过envelope.errors.execution / other控制哪些错误收进信封。善用类型驱动errorChannel: return会把错误类型并入返回值的联合类型配合 TypeScript 的穷尽检查可以确保每条请求路径都显式处理错误分支。配置来源多样output配置既可在Graffle.create()中一次性声明也可通过.with()方法在既有客户端实例上增量覆盖如测试 with_output.test.ts 中的g1.with({ output: { defaults: { errorChannel: return } } })方便针对不同调用场景切换错误策略。小结Graffle 的output配置提供了一条从异常驱动到返回值驱动的平滑路径defaults.errorChannel: return一键切换全局错误通道errors.execution / other实现对执行错误与其他错误的分流类型系统同步收窄返回类型让错误分支在编译期即可被感知。配合handleOutput的运行时分发与ContextualError/ContextualAggregateError的丰富诊断上下文你可以为不同的 GraphQL 请求场景定制一致且可预期的错误处理体验。进一步阅读可在仓库中查看 output 配置片段、输出处理实现 以及 输出相关官方示例。赞分享后端【免费下载链接】graffleSimple GraphQL Client for JavaScript. Minimal. Extensible. Type Safe. Runs everywhere.项目地址https://gitcode.com/gh_mirrors/gr/graffle点击查看免费下载相关推荐免费的 Jellyfin 桌面播放器告别浏览器卡顿5 分钟跑起家庭影院免费的 Jellyfin 桌面播放器告别浏览器卡顿5 分钟跑起家庭影院 Jellyfin Desktop 是一款免费开源的桌面播放器它把 Jellyfin后端Graffle 配置指南在 Envelope 输出模式下抛出错误output.envelope.errors 详解Graffle 配置指南在 Envelope 输出模式下抛出错误output.envelope.errors 详解 本文讲解 Graffle GraphQ后端Graffle 输出配置实战用 Preset.traditionalGraphqlOutput 还原传统 GraphQL ExecutionResult 行为Graffle 输出配置实战用 Preset.traditionalGraphqlOutput 还原传统 GraphQL ExecutionResult 行为后端上一篇请求日志分析器Request Log Analyzer安装与使用指南下一篇WidescreenFixesPack完整指南如何为100游戏添加宽屏分辨率支持创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

PaddleX 车辆检测模块实战指南:从 PP-YOLOE 模型推理到自定义训练全流程

PaddleX 车辆检测模块实战指南:从 PP-YOLOE 模型推理到自定义训练全流程

人工智能大模型低代码计算机视觉深度学习模型推理服务 【免费下载链接】PaddleX All-in-One Development Tool based on PaddlePaddle 项目地址: https://gitcode.com/gh_mirrors/pa/PaddleX 点击查看 免费下载 车辆检测是目标检测的一个重要子任务,它利…

2026/10/10 1:19:36 阅读更多 →
int4-g32+warm 裸量化:原理与实验报告

int4-g32+warm 裸量化:原理与实验报告

零校准 零修正 3.8x 压缩 QA 75.3% —— 全项目性价比最高的可部署配置 模型: MiniCPM5-2B (32层) | 硬件: RTX 2070 8GB 定位: 本报告是该配置的独立完整文档, 汲取自《量化函数族探索_完整报告.md》 与《多参数量化扩展_实验与原理报告.md》两份前报告的结论, 并含最新的归…

2026/10/10 1:19:36 阅读更多 →
Go 语言调用 Azure AD 认证实战:go-autorest/adal 库完整指南

Go 语言调用 Azure AD 认证实战:go-autorest/adal 库完整指南

云原生后端前端运维可观测性开发工具 【免费下载链接】octant Highly extensible platform for developers to better understand the complexity of Kubernetes clusters. 项目地址: https://gitcode.com/gh_mirrors/oc/octant 点击查看 免费下载 本文以 vendor/g…

2026/10/10 1:19:36 阅读更多 →

最新新闻

项目排障这件事AI 只能算帮手,思路得你自己有

项目排障这件事AI 只能算帮手,思路得你自己有

嵌入式排障方法论 硬件配套问题的多渠道解决思路:商家、AI、社区,还有你自己的判断 做一个嵌入式项目,你会发现问题从来不是一个一个来的,是一串一串来的。尤其是硬件和硬件的配套——两家的板子接在一起,谁也不保证…

2026/10/10 2:03:50 阅读更多 →
Vue .sync修饰符深入解析:父子组件双向绑定与v-model区别

Vue .sync修饰符深入解析:父子组件双向绑定与v-model区别

我对 .sync 的第一印象,来自一个困扰我整个下午的 bug:父组件传了个 visible 给弹窗子组件,子组件里想关掉它,却发现怎么点按钮都关不掉。后来查了资料才明白,Vue 的父子组件通信里有一条铁律——子组件不能直接改 pro…

2026/10/10 2:03:50 阅读更多 →
C#初学者必看:从类与对象到封装属性的完整实战指南

C#初学者必看:从类与对象到封装属性的完整实战指南

今天这篇是 C# 初学者每日分享系列的第 13 篇。如果你是从前面几篇一路跟过来的,应该已经见过变量、判断、循环、方法、数组这些基础语法了;如果今天才点开,也没关系,这一篇我会从类与对象最基础的概念讲起,一步一步带…

2026/10/10 2:03:50 阅读更多 →
mergerfs link-cow 选项深度解析:硬链接文件的写时复制(CoW)语义

mergerfs link-cow 选项深度解析:硬链接文件的写时复制(CoW)语义

存储 【免费下载链接】mergerfs a featureful union filesystem 项目地址: https://gitcode.com/gh_mirrors/me/mergerfs 点击查看 免费下载 本篇聚焦 mergerfs 的 link-cow 配置项:它让"对硬链接文件打开写"这一操作自动、原子地断裂链接&am…

2026/10/10 2:03:50 阅读更多 →
Midway Hooks 一体化开发指南:用 React Hooks 语法编写全栈应用

Midway Hooks 一体化开发指南:用 React Hooks 语法编写全栈应用

后端微服务云原生 【免费下载链接】midway 🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate w…

2026/10/10 2:03:50 阅读更多 →
6 天 1000 星就是风口?警惕技能包赛道的刷星与注水

6 天 1000 星就是风口?警惕技能包赛道的刷星与注水

6 天 1000 星就是风口?警惕技能包赛道的刷星与注水 【免费下载链接】replica-skill Eleven free Claude skills that clone any app: reverse-engineer it, rebuild it, test it for bugs, then fix what its users hate. Free, MIT. 项目地址: https://gitcode.c…

2026/10/10 2:02:49 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →