后端【免费下载链接】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),仅供参考