如何用 tRPC errorFormatter 把 Zod 校验错误以类型安全方式传给客户端展示

发布时间:2026/9/11 1:40:03

如何用 tRPC errorFormatter 把 Zod 校验错误以类型安全方式传给客户端展示 如何用 tRPC errorFormatter 把 Zod 校验错误以类型安全方式传给客户端展示【免费下载链接】trpc‍♀️ Move Fast and Break Nothing. End-to-end typesafe APIs made easy.项目地址: https://gitcode.com/GitHub_Trending/tr/trpc假设你的 tRPC API 用 Zod 校验了 procedure 的入参。当客户端提交了非法输入时默认响应里只有一句password must be at least 4 characters这样的通用 message拿不到“哪个字段、什么错误”的结构化信息也就没法在表单里逐条渲染。本文的目标就是在服务端用initTRPC的errorFormatter把ZodError的flatten()结果放进错误对象的data里并让这份结构一路推导infer到 React 客户端使mutation.error.data.zodError在编辑器里是具体类型而不是unknown从而可以直接读取字段并展示。整条路径依据 error formatting 文档给出的服务端errorFormatter与 React 用法示例入参与依赖安装分别参考 validators 和 React 集成 setup。前提条件按 React 集成 setup 的说明这套 React 集成需要安装以下依赖trpc/react-query依赖tanstack/react-querynpm install trpc/server trpc/client trpc/react-query tanstack/react-query此外服务端示例用到了zod因为示例中的入参校验基于 Zod。服务端示例里用到了initTRPC、ZodError、z分别来自trpc/server和zod。服务端在 initTRPC.create 里挂 errorFormattererrorFormatter在initTRPC.create()里配置。文档说明router 里的错误格式会一路推导到客户端The error formatting in your router will be inferred all the way to your client这正是类型安全的关键——你在服务端返回的data结构决定了客户端能读到什么类型。下面这段是 error formatting 文档中 React 示例所给出的完整服务端代码server.tsimport { initTRPC } from trpc/server; import { ZodError } from zod; import { z } from zod; const t initTRPC.create({ errorFormatter(opts) { const { shape, error } opts; return { ...shape, data: { ...shape.data, zodError: error.code BAD_REQUEST error.cause instanceof ZodError ? error.cause.flatten() : null, }, }; }, }); export const appRouter t.router({ addPost: t.procedure.input(z.object({ title: z.string() })).mutation(({ input }) input), }); export type AppRouter typeof appRouter;几个需要理解的点都来自 error formatting 文档errorFormatter(opts)收到的opts包含error、type、path、input、ctx、shape其中shape是{ message: string; code: number; data: unknown }。error.cause instanceof ZodError配合error.code BAD_REQUEST用来识别“这是入参校验失败”。只有命中该条件时才填充zodError否则为null。这里用...shape.data保留了默认错误数据的字段。默认的DefaultErrorData含code、httpStatus、path?以及仅开发环境出现的stack?。也就是说errorFormatter是在默认错误结构之上追加zodError字段而不是替换整个响应。默认错误结构可以对照 error handling 文档给出的入参错误示例code为-32600、data.code为BAD_REQUEST、data.httpStatus为400。客户端创建 hooks 并读取推导出来的错误在客户端用一个文件导出createTRPCReactAppRouter()创建的trpc对象它从服务端的AppRouter类型推导出所有 hook来自文档中的utils/trpc.tsximport { createTRPCReact } from trpc/react-query; import type { AppRouter } from ../server; export const trpc createTRPCReactAppRouter();然后在组件里用useMutation触发那个带 Zod 输入的 procedure并读取mutation.error.data.zodError。下面是文档中components/MyComponent.tsx的用法import { useEffect } from react; import { trpc } from ../utils/trpc; export function MyComponent() { const mutation trpc.addPost.useMutation(); useEffect(() { mutation.mutate({ title: example }); }, []); if (mutation.error?.data?.zodError) { // zodError will be inferred return ( preError: {JSON.stringify(mutation.error.data.zodError, null, 2)}/pre ); } return [...]/; }说明useEffect里的mutation.mutate(...)是文档用来触发一次调用、从而走到错误分支的写法实际项目里通常由用户操作触发 mutation。末尾的[...]/是文档里“组件其余 UI”的占位写法替换成你组件正常的返回内容即可。关键在if (mutation.error?.data?.zodError)由于服务端errorFormatter的返回结构被推导到了客户端mutation.error.data.zodError在这里是ZodError.flatten()的结构类型而不是unknown因此可以直接按字段读取并展示。结果验证文档给出的判断方式有两层类型层面——文档明确注释 “zodError will be inferred”即mutation.error.data.zodError由服务端errorFormatter的返回类型推导而来。在编辑器里悬停或访问其子字段时你会得到flatten()的结构而不是unknown这是“类型安全传给客户端”的直接体现。运行时层面——当入参不满足 Zod schema 时服务端返回BAD_REQUEST且error.cause是ZodErrorif (mutation.error?.data?.zodError)分支命中组件用JSON.stringify(mutation.error.data.zodError, null, 2)渲染出该错误对象。限制与说明errorFormatter的zodError只在error.code BAD_REQUEST error.cause instanceof ZodError时填充否则为null。它针对的是入参校验失败validators 文档指出输出校验失败会以INTERNAL_SERVER_ERROR响应不会被这里的zodError覆盖。默认错误数据中的stack只在开发环境出现error handling 说明initTRPC.create()默认把isDev设为process.env.NODE_ENV ! production需要确定性行为时可手动传isDev。tRPC 兼容 JSON-RPC 2.0shape.code是数字如-32600而data.code是BAD_REQUEST这类TRPC_ERROR_CODE_KEY两者不是同一字段读取时注意区分。更多错误码表与TRPCError、onError的用法见 error handlinginferRouterInputs/inferRouterOutputs等从AppRouter推导类型的手动方式见 Inferring Types。【免费下载链接】trpc‍♀️ Move Fast and Break Nothing. End-to-end typesafe APIs made easy.项目地址: https://gitcode.com/GitHub_Trending/tr/trpc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/11 1:35:03

千笔与云笔AI降AI率实测:从78%到19%的改写差异

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

2026/9/11 1:35:03

3步快速把SystemInformer切成中文界面:多语言配置实战

3步快速把SystemInformer切成中文界面:多语言配置实战 【免费下载链接】systeminformer A free, powerful, multi-purpose tool that helps you monitor system resources, debug software and detect malware. Brought to you by Winsider Seminars & Solution…

2026/9/11 2:35:09

声振温监测方案拆解:从传感器选型到可视化看板落地

设备管理人员最怕的,从来不是“设备坏了”这件事本身,而是“不知道它快坏了”。传统模式下,转动设备就像一台关在铁皮柜子里的黑箱——巡检员拿听音棒贴上去听一听,用手背试一下壳体温度,再凭经验判断“还行”或者“有…

2026/9/11 2:35:09

2026年RFID技术演进:智能感知与边缘计算融合

1. RFID技术演进与产业升级背景2026年的RFID读写器将不再是简单的数据采集工具,而是演变为具备环境感知能力的智能终端。这种转变源于三个关键驱动力:首先,制造业对实时数据的需求从"有没有"升级为"准不准";其…

2026/9/11 2:35:09

CMSIS-5源码深度解析:架构、DSP/NN库与工程落地实践

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

2026/9/10 16:39:38

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/10 11:16:38

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 12:32:02

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

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

2026/9/10 15:19:50

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

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

2026/9/10 15:49:53

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

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

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

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

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