
后端【免费下载链接】graffleSimple GraphQL Client for JavaScript. Minimal. Extensible. Type Safe. Runs everywhere.项目地址https://gitcode.com/gh_mirrors/gr/graffle点击查看免费下载本篇指南讲解 GraffleSimple GraphQL Client for JavaScript中output.envelope输出模式下的错误通道配置。你将掌握如何通过envelope.errors.execution与envelope.errors.other两个开关决定执行错误与“其他错误”如网络错误、扩展抛出的错误是嵌入信封envelope的errors字段还是直接抛出异常并结合 Graffle 源码理解这一决策在运行时与类型层面的完整实现路径。示例场景开启信封但依然抛错Graffle 的 envelope 输出模式会把结果包装为{ data, errors, extensions }结构。默认情况下当错误类别对应的开关为true时错误会被放入 envelope 的errors数组中而非抛出而本示例website/content/examples/20_output/envelope-error-throw.md演示的则是相反的场景即使启用了 envelope也强制让错误以异常形式抛出。完整示例代码examples/20_output/output_envelope_envelope_error-throw__envelope-error-throw.tsimport { Graffle } from ../$/graffle/_.js // dprint-ignore const pokemon Graffle .create({ output: { envelope: { errors: { execution: false, other: false, // default } }, }, }) .anyware(({ encode: _ }) { throw new Error(Something went wrong.) //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ }) await pokemon.query.pokemons({ name: true })运行后输出实际运行产物见 examples/outputs/20_output/output_envelope_envelope_error-throw__envelope-error-throw.output.txt/some/path/to/runPipeline.ts:XX return new ContextualError(message, { ^ ContextualError: 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_envelope_envelope_error-throw__envelope-error-throw.ts:XX:XX) { context: { hookName: encode, source: extension, interceptorName: anonymous }, cause: Error: Something went wrong. at anonymous (/some/path/to/output_envelope_envelope_error-throw__envelope-error-throw.ts:XX:XX) at applyBody (/some/path/to/runner.ts:XX:XX) } Node.js vXX.XX.XX可以看到await pokemon.query.pokemons(...)并没有返回 envelope 对象而是直接抛出了ContextualError——它携带了原始错误cause: Error: Something went wrong.以及丰富的错误上下文hookName、source、interceptorName。envelope.errors 两个开关的含义与默认值output.envelope.errors是长格式longhand配置控制两类错误的去向其类型定义位于 src/context/fragments/configuration/output/configuration.ts配置项含义默认值envelope.errors.execution执行错误即传统 GraphQL 执行结果中errors字段里的错误如字段解析失败、校验错误true嵌入 envelopeenvelope.errors.other其他错误包括 HTTP 传输层 fetch 抛出的网络错误、扩展extension内抛出的错误等false不嵌入走默认通道其归一化默认值在源码default_对象中configuration.tsconst default_ { defaults: { errorChannel: throw, // 默认错误通道抛出 }, envelope: { enabled: false, // 信封默认关闭 errors: { execution: true, // 执行错误默认嵌入信封 other: false, // 其他错误默认不嵌入 }, }, errors: { execution: default, other: default, }, }注意这里的两层设计errors.execution / errors.other顶层可显式指定throw | return | defaultdefault表示回落到defaults.errorChannel默认为throw。envelope.errors.execution / other布尔控制是否把对应类别错误嵌入信封当其为false时该类别错误不进入信封转而按顶层错误通道处理。本示例将两者都设为false于是扩展抛出的错误既不进信封又因默认通道是throw而直接抛出。对比嵌入信封的版本为了看清“抛出”与“嵌入”的区别可对比姊妹示例 website/content/examples/20_output/envelope-error.md 及其源码 examples/20_output/output_envelope_envelope-error__envelope-error.ts。它只把两个开关改为trueconst pokemon Graffle .create({ output: { envelope: { errors: { execution: true, // default other: true, }, }, }, }) .anyware(({ encode: _ }) { throw new Error(Something went wrong.) }) const result await pokemon.query.pokemons({ name: true }) console.log(result)此时同样的错误不再抛出而是出现在返回结果的errors数组中见 examples/outputs/20_output/output_envelope_envelope-error__envelope-error.output.txt{ errors: [ ContextualError: There was an error in the interceptor anonymous (use named functions to improve this error message) while running hook encode. ... context: { hookName: encode, source: extension, interceptorName: anonymous }, cause: Error: Something went wrong. ... } ] }两张输出对比一目了然同一处throw new Error(...)开关为true时错误被俘获进信封开关为false时错误被原样抛出。这正是 Graffle 输出配置“细粒度控制”能力的体现。源码解析错误通道是如何被决策的运行时readErrorCategoryOutputChannel 与 handleOutput错误最终的走向由客户端输出处理函数handleOutput决定src/client/handle.ts。它先从配置读取每个错误类别的实际通道export const readErrorCategoryOutputChannel ( output: Normalized, errorCategory: ErrorCategory, ): OutputChannel | false { if (output.errors[errorCategory] default) { return output.defaults.errorChannel } return output.errors[errorCategory] }见 configuration.ts——即default回落为defaults.errorChannel。随后handleOutput依据“是否启用信封 该类别是否嵌入信封”组合出四个布尔判断handle.tsconst 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)对“其他错误”本示例由 anyware 扩展在encode钩子抛出而言当结果为Error时if (result instanceof Error) { if (isThrowOther) throw result if (isReturnOther) return result return isEnvelope ? { errors: [result] } : result }在本示例配置envelope.enabled为真、envelope.errors.other为false、默认通道为throw下isThrowOther true于是throw result——错误直接抛出封装为ContextualError。ContextualError来自wollybeard/kit的Err命名空间handle.ts 中同类错误亦用new Err.ContextualError构造其context字段记录了hookName: encode、source: extension、interceptorName: anonymouscause指向原始Error: Something went wrong.。这也解释了输出信息中“use named functions to improve this error message”的提示——给 anyware 拦截器命名可以提升排错体验。类型层面HandleOutput 如何推导返回类型handleOutput的运行时分支在类型系统中有对应的映射handle.ts。关键的ConfigGetOutputError会先判断信封是否启用export type ConfigGetOutputError $OutputConfig extends Normalized, $ErrorCategory extends ErrorCategory, $OutputConfig[envelope][enabled] extends true ? ConfigGetOutputEnvelopeErrorChannel$OutputConfig, $ErrorCategory : ConfigResolveOutputErrorChannel$OutputConfig, $OutputConfig[errors][$ErrorCategory]而ConfigGetOutputEnvelopeErrorChannel在“该类别嵌入信封为true”时返回false即不会作为错误返回否则回落解析真实通道type ConfigGetOutputEnvelopeErrorChannel $OutputConfig extends Normalized, $ErrorCategory extends ErrorCategory, $OutputConfig[envelope][errors][$ErrorCategory] extends true ? false : ConfigResolveOutputErrorChannel$OutputConfig, $OutputConfig[errors][$ErrorCategory]配合IfConfiguredGetOutputErrorReturnshandle.ts当类别通道解析为return时返回类型会并入对应错误类型。因此本示例中envelope.errors.other: false意味着 TS 推导的返回类型不会包含“返回错误”的分支——调用方可以放心地按成功数据或异常处理。进一步组合return 通道与信封共存除了throwGraffle 还支持把错误放进返回值而非抛出。将默认错误通道改为return不启用信封的示例见 website/content/examples/20_output/return-error.md 与 website/content/examples/20_output/return-error-execution.mdconst 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 })此时pokemons的类型会推导为“数据 | ContextualError”的联合示例中通过type _pokemons typeof pokemons上的// ^?悬浮提示可见调用方必须显式判别错误分支。这与本示例“信封 抛出”形成两种互补的错误处理风格信封 errors: { execution: false, other: false }错误抛出throw异常路径清晰信封 errors: { execution: true, other: true }错误嵌入信封errors数组数据路径统一关闭信封 errorChannel: return错误作为返回值返回类型系统强制处理。小结Graffle 的output配置用“错误类别execution/other× 输出通道throw/return/ 信封嵌入”的二维模型为错误处理提供了细粒度的控制envelope.errors.execution与envelope.errors.other控制对应错误是否嵌入信封顶层errors.execution / errors.other与defaults.errorChannel决定未嵌入信封时的最终通道默认throw运行时由 handleOutput 执行分支决策类型层面由HandleOutput系列类型同步推导返回类型保证“配置即类型”。当你在使用 envelope 输出模式却希望错误“藏不住”时只需把对应类别开关设为false就能得到本示例中直接抛出ContextualError的行为——既保留信封对成功数据{ data }的结构化包装又让异常不被吞没。赞分享后端【免费下载链接】graffleSimple GraphQL Client for JavaScript. Minimal. Extensible. Type Safe. Runs everywhere.项目地址https://gitcode.com/gh_mirrors/gr/graffle点击查看免费下载相关推荐Graffle 配置指南在 Envelope 输出模式下抛出错误output.envelope.errors 详解Graffle 配置指南在 Envelope 输出模式下抛出错误output.envelope.errors 详解 本文讲解 Graffle GraphQ后端Graffle 信封Envelope模式下强制抛出错误的配置指南output.envelope.errors 详解Graffle 信封Envelope模式下强制抛出错误的配置指南output.envelope.errors 详解 导读 本文围绕 Graffle 客户端后端Graffle 输出配置实战Envelope 信封模式全解析Graffle 输出配置实战Envelope 信封模式全解析 导读 本篇文章聚焦 Graffle一个极简、可扩展、类型安全的 JavaScript Grap后端上一篇g2b-sanctioned-supplier 技能实战经 k-skill-proxy 查询韩国调达厅(나라장터)不正当制裁企业信息下一篇policy.useIsAuthorized在 Wagmi 中检查地址是否被转账策略授权创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考