ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

mobx-state-tree 的 IValidationError 类型校验错误结构详解:context / value / message 字段与运行时校验机制

mobx-state-tree 的 IValidationError 类型校验错误结构详解:context / value / message 字段与运行时校验机制 状态管理前端【免费下载链接】mobx-state-treeFull-featured reactive state management without the boilerplate项目地址https://gitcode.com/gh_mirrors/mo/mobx-state-tree点击查看免费下载导读IValidationError是 mobx-state-treeMST在运行时进行快照/实例类型校验时用来描述某处校验失败的核心数据结构。本文以官方 API 文档中该接口的完整定义docs/API/interfaces/ivalidationerror.md为主体结合仓库源码 src/core/type/type-checker.ts、src/core/type/type.ts 与测试用例tests/core/error-formatting.test.ts逐字段讲解context、value、message的含义与产生过程并延伸到IValidationContext、IValidationResult、typecheck()手动校验以及错误信息格式化配置帮助读者掌握 MST 类型系统的校验链路与排错方法。IValidationError 是什么IValidationErrorType validation error是 MST 类型系统中最小的校验失败单元。它不是一个会被抛出并中断流程的异常对象而是一条结构化的错误描述记录任何一次类型校验最终都会返回一个由IValidationError组成的数组只有当数组为空时校验才算通过。在 src/core/type/type-checker.ts 中接口定义如下/** Type validation error */ export interface IValidationError { /** Validation context */ context: IValidationContext /** Value that was being validated, either a snapshot or an instance */ value: any /** Error message */ message?: string }三个字段分别是字段类型必填含义contextIValidationContext是校验上下文即在哪条路径上、用哪个类型做校验valueany是被校验的值可能是快照snapshot或实例instancemessagestring \| undefined否可选的补充错误信息此外type-checker.ts还定义了与之配套的两个别名/** Array of validation context entries */ export type IValidationContext IValidationContextEntry[] /** Type validation result, which is an array of type validation errors */ export type IValidationResult IValidationError[]即context是多个上下文条目的数组而整个校验的结果IValidationResult是IValidationError的数组。校验成功时返回空数组源码中的typeCheckSuccess()直接返回共享的EMPTY_ARRAY校验失败时通过typeCheckFailure()构造并返回含单条错误的数组src/core/type/type-checker.tsexport function typeCheckFailure( context: IValidationContext, value: any, message?: string ): IValidationResult { return [{ context, value, message }] }可以看到IValidationError的构造与typeCheckFailure的入参一一对应message传不传都可选这与接口中message?的可选性完全一致。context错误发生在哪条路径context的类型IValidationContext在 src/core/type/type-checker.ts 中有明确说明/** Validation context entry, this is, where the validation should run against which type */ export interface IValidationContextEntry { /** Subpath where the validation should be run, or an empty string to validate it all */ path: string /** Type to validate the subpath against */ type: IAnyType } /** Array of validation context entries */ export type IValidationContext IValidationContextEntry[]context是一个从根到出错节点的路径栈其中每个条目记录两件事——path表示相对子路径空字符串表示校验整体type表示该子路径应对应的类型。随着校验不断深入嵌套结构校验器会通过getContextForPath()把新条目追加到上下文末尾src/core/type/type-checker.tsexport function getContextForPath( context: IValidationContext, path: string, type: IAnyType ): IValidationContext { return context.concat([{ path, type }]) }以数组类型为例在 src/types/complex-types/array.ts 中数组校验失败时返回的正是带路径的失败信息而对每个元素做递归校验时会把下标拼进路径this._subType.validate(item, getContextForPath(context, index, this._subType))这样累积出来的 context 链在错误渲染时会被还原成完整的出错路径。看 type-checker.ts 中toErrorString()的实现const fullPath error.context .map(({ path }) path) .filter(path path.length 0) .join(/) const pathPrefix fullPath.length 0 ? at path /${fullPath} : 也就是说一条真实产生的校验错误消息会以at path /xxx/yyy的形式告诉用户问题出在树的哪个位置这正是context字段的实战价值——它让开发者一眼定位到模型深处的出错属性。value被校验的值value是正在被校验的那个值它既可能是快照普通对象也可能是 MST 实例state tree node。接口文档明确写着Value that was being validated, either a snapshot or an instance。这一双重身份在错误渲染时会被区分对待见toErrorString()src/core/type/type-checker.tsconst currentTypename isStateTreeNode(value) ? value of type ${getStateTreeNode(value).type.name}: : isPrimitive(value) ? value : snapshot如果value是状态树节点instance错误消息会说value of type Xxx:如果是基本类型值统称value如果是普通对象快照形态则称snapshot。value的展示也经过了专门处理prettyPrintValue()会调用JSON.stringify序列化遇到函数显示为function name遇到状态树节点显示为值在启用错误格式化时还会进一步截断超长字符串、超大数组/对象与深层嵌套避免错误信息刷屏src/core/type/type-checker.ts。message可选的补充说明message是唯一可选字段message?用于承载校验器给出的为什么失败的补充说明。比如数组类型在 src/types/complex-types/array.ts 中返回return typeCheckFailure(context, value, Value is not an array)这条Value is not an array就会存入IValidationError.message最终在错误消息中以括号形式追加显示见 type-checker.ts(error.message ? (${error.message}) : )因此message的语义是附加解释而主体信息路径、类型名、值内容由context与value提供。三者组合起来构成一条完整的、可直接读懂的校验失败描述。IValidationError 的产生与消费链路1. 产生validate()返回错误数组每个 MST 类型都实现了IType.validate(thing, context)接口定义见 src/core/type/type.ts返回IValidationResult。BaseType.validate()的默认实现src/core/type/type.ts对实例做类型可赋值性检查对快照交给isValidSnapshot做递归校验。2. 汇总typecheck()把错误数组变成异常对外暴露的typecheck(type, value)src/core/type/type-checker.ts是手动触发校验的入口无论开发/生产环境都会执行export function typecheckIT extends IAnyType(type: IT, value: ExtractCSTWithSTNIT): void { const errors type.validate(value, [{ path: , type }]) if (errors.length 0) { throw new MstError(validationErrorsToString(type, value, errors)) } }可以看到初始上下文正是[{ path: , type }]——即整个值按该类型校验这与IValidationContextEntry.path的空字符串表示校验整体的注释互相印证。校验产生的IValidationError[]在这里被拼接成一条可读的MstError异常抛出。3. 渲染validationErrorsToString()逐条格式化validationErrorsToString 会把IValidationError数组渲染成如下格式默认、未启用格式化时Error while converting {x:nope} to Model: at path /x value nope is not assignable to type: number (Value is not a number).这条真实输出在测试tests/core/error-formatting.test.ts 中被完整断言可以作为理解IValidationError渲染结果的直观样例。其中at path /x来自context路径拼接nope来自value序列化Value is not a number来自message。4. 运行时入口typecheckInternal()日常开发中你未必直接调用typecheck()——MST 在create()、applySnapshot()、属性赋值等场景会通过typecheckInternal()src/core/type/type-checker.ts静默触发校验export function typecheckInternalIT extends IAnyType( type: IAnyType, value: ExtractCSTWithSTNIT ): void { // runs typeChecking if it is in dev-mode or through a process.env.ENABLE_TYPE_CHECK flag if (isTypeCheckingEnabled()) { typecheck(type, value) } }注意该函数只在开发模式或设置了ENABLE_TYPE_CHECK环境变量时才真正执行校验生产构建默认跳过以换取性能。BaseType.create()src/core/type/type.ts与数组属性赋值src/types/complex-types/array.ts等场景均依赖它。结合源码如何读懂并定制校验错误IValidationError的三个字段配合 errorFormatting.ts 中的setErrorFormatting() / getErrorFormatting()可以在不改变校验逻辑的前提下控制错误信息的排版与截断。默认配置测试断言见tests/core/error-formatting.test.ts为{ enabled: false, // 默认关闭保持单行紧凑输出 indent: 2, // 启用后每层缩进 2 空格 maxStringLength: 100, // 超过 100 字符的字符串被截断 maxArrayLength: 10, // 超过 10 项的数组被截断 maxPropertyCount: 30, // 超过 30 个键的对象被截断 maxDepth: 5 // 嵌套深度超过 5 层折叠为 {…} / […] }常用定制方式src/core/type/errorFormatting.tsimport { setErrorFormatting } from mobx-state-tree // 多行美化输出并截断超大快照 setErrorFormatting({ enabled: true }) // 只限制消息长度不换行 setErrorFormatting({ enabled: true, indent: 0 }) // 收紧截断阈值 setErrorFormatting({ enabled: true, maxArrayLength: 3, maxStringLength: 40 })其内部实现truncateForDisplay会递归克隆并裁剪值长字符串追加… (N more characters)大数组追加… N more items超深嵌套折叠为[…]/{…}。由于选项是全局状态且getErrorFormatting()返回副本errorFormatting.ts测试中通过先快照后恢复的方式保证隔离tests/core/error-formatting.test.ts在应用代码里若需临时覆盖也建议采用同样的保存/恢复模式。排查实战一次校验失败的完整解读假设存在模型const Model types.model(Model, { x: types.number })并调用Model.create({ x: nope })。实际流程为BaseType.create()调用typecheckInternal()因处于开发模式而执行typecheck(Model, { x: nope })type.validate(value, [{ path: , type: Model }])对快照递归校验属性x校验失败生成IValidationErrorcontext为[{ path: , type: Model }, { path: x, type: number }]value为字符串nopemessage为Value is not a number该消息由 src/types/primitives.ts 中数值类型的isValidSnapshot提供typecheck()检测到errors.length 0将错误数组渲染为MstError抛出最终呈现为Error while converting {x:nope} to Model: at path /x value nope is not assignable to type: number (Value is not a number).整条消息的每一个组成部分——路径前缀、值序列化、类型名、括号里的补充说明——都分别对应IValidationError.context、.value、.message三个字段理解这一映射关系就能在任何报错面前快速定位哪个路径、哪个值、因为什么。总结IValidationError是 MST 运行时类型校验的最小数据结构context定位出错路径与期望类型value承载出错的快照或实例可选的message补充失败原因。它由各类型的validate()产生、经typecheck()/typecheckInternal()汇总抛出再经toErrorString()渲染成可读的错误消息。想更深入地排查与定制校验行为可继续阅读同一模块的 src/core/type/type-checker.ts、配套上下文类型 docs/API/interfaces/ivalidationcontextentry.md以及错误格式化配置 src/core/type/errorFormatting.ts。赞分享状态管理前端【免费下载链接】mobx-state-treeFull-featured reactive state management without the boilerplate项目地址https://gitcode.com/gh_mirrors/mo/mobx-state-tree点击查看免费下载相关推荐DeepChat 数据落盘位置权威指南从主数据库到加密元数据、备份布局与快照导入规则DeepChat 数据落盘位置权威指南从主数据库到加密元数据、备份布局与快照导入规则 本文基于 DeepChat 仓库中供数据导入工具使用的参考文档 data状态管理前端jose 中 JWT Claim 校验失败错误结构 JWTClaimValidationFailure 详解字段、错误码与实战排查jose 中 JWT Claim 校验失败错误结构 JWTClaimValidationFailure 详解字段、错误码与实战排查 导读 本文围绕 jose网络安全认证鉴权后端Rematch rematch/typed-state 插件用 prop-types 对 Redux State 做运行时类型校验Rematch rematch/typed state 插件用 prop types 对 Redux State 做运行时类型校验 在 TypeScript前端上一篇从第一次提交到核心开发者金庸群侠传3D重制版(jynew)开源贡献完整路径下一篇Kodi字幕库插件智能字幕下载的完整解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表