feat: add ValidationHandler to JSONSchema for fail-safe error collection, for issue #3912#3968
feat: add ValidationHandler to JSONSchema for fail-safe error collection, for issue #3912#3968jujn wants to merge 4 commits intoalibaba:mainfrom
Conversation
|
@MonkeyCode-AI review 一下 |
|
MonkeyCode-AI 正在分析任务... |
MonkeyCode-AI
left a comment
There was a problem hiding this comment.
我是 MonkeyCode AI 编程助手,你可以在 GitHub 仓库的 PR 中 at @MonkeyCode-AI 来呼唤我。
任务执行细节请参考: https://monkeycode-ai.com/tasks/public?id=51e2b2b6-be8e-42e2-82bd-298457dcc212
代码审查结果
本 PR 通过引入 ValidationHandler 让 Fail-Safe/Fail-Fast 并存且测试较完善,但仍存在组合校验绕过 handler、错误封装不一致与可诊断性不足等问题,建议修复后再合入。
✨ 代码亮点
- 通过 ValidationHandler + abort 标志实现 Fail-Safe / Fail-Fast 双模式,API 简洁直观
- JSONSchema.handleError 将 custom error message 解析与 handler 回调集中封装,降低各 Schema 重复逻辑
- 新增 Issue3912 单元测试覆盖了收集全部错误、提前中断、嵌套对象/数组、dependentRequired、additionalProperties、uniqueItems 等关键场景
| 🚨 Critical | 💡 Suggestion | |
|---|---|---|
| 1 | 0 | 0 |
| if (anyOf != null) { | ||
| ValidateResult result = anyOf.validate(str); | ||
| ValidateResult result = anyOf.validateInternal(str, handler, path); | ||
| if (!result.isSuccess()) { | ||
| return result; | ||
| } | ||
| } | ||
|
|
||
| if (oneOf != null) { | ||
| ValidateResult result = oneOf.validate(str); | ||
| ValidateResult result = oneOf.validateInternal(str, handler, path); | ||
| if (!result.isSuccess()) { | ||
| return result; | ||
| } |
There was a problem hiding this comment.
Caution
🚨 StringSchema 对 anyOf/oneOf 子校验失败时直接 return,可能绕过 handler(无法收集错误)
StringSchema 在处理 anyOf/oneOf 时调用 validateInternal(str, handler, path),但失败时直接 return result,没有确保 handler 一定被触发。
另外 anyOf/oneOf 内部常用 validateInternal(value, null, path) 做探测(PR 中也如此),因此即便 StringSchema 传入 handler,失败结果也可能来自“handler 被刻意屏蔽的探测分支”,导致 validate(...) 返回失败但 handler 未收到回调,违背全量错误收集目标。类似风险可能也存在于其他叶子节点对组合 schema 的调用路径。
建议: 对 anyOf/oneOf 这类组合节点,建议统一由组合节点自身在失败时调用 handleError(handler, ...) 触发回调;或在 StringSchema 这里对失败 result 做一次 handleError 包装,确保 handler 一定会收到错误事件(并尊重 result.isAbort())。
| if (anyOf != null) { | |
| ValidateResult result = anyOf.validate(str); | |
| ValidateResult result = anyOf.validateInternal(str, handler, path); | |
| if (!result.isSuccess()) { | |
| return result; | |
| } | |
| } | |
| if (oneOf != null) { | |
| ValidateResult result = oneOf.validate(str); | |
| ValidateResult result = oneOf.validateInternal(str, handler, path); | |
| if (!result.isSuccess()) { | |
| return result; | |
| } | |
| if (anyOf != null) { | |
| ValidateResult result = anyOf.validateInternal(str, handler, path); | |
| if (!result.isSuccess()) { | |
| return handler == null ? result : handleError(handler, value, path, result); | |
| } | |
| } | |
| if (oneOf != null) { | |
| ValidateResult result = oneOf.validateInternal(str, handler, path); | |
| if (!result.isSuccess()) { | |
| return handler == null ? result : handleError(handler, value, path, result); | |
| } | |
| } |
What this PR does / why we need it?
在 JSONSchema 加入 ValidationHandler 以支持全量错误收集(已支持全量收集自定义错误信息),通过回调机制允许用户控制校验流程(中断/继续)。
代码示例:
使用示例①
使用示例②(Web请求校验)
Summary of your change