feat(failure-rules): 错误类型枚举强校验 + 多选 UI#187
Merged
Merged
Conversation
把上游失败规则的 error_types 字段从自由 CSV 升级为封闭枚举: - 新增 src/lib/constants/failover-error-types.ts 作为 FailoverErrorType 的运行时单一来源(数组 + zod enum + 类型守卫),让前后端共享。 - 三处 admin route schema(全局 POST、单条 PUT、scoped POST)改用 z.array(failoverErrorTypeSchema),拼错会直接 400。 - 服务层 assertValidRuleMatch 增加 enum 校验作为第二防线;ruleMatchesEvidence 命中含未知值的历史规则时以 per-rule 去重的方式 log.warn 一次,让运维通过日志感知到沉默失效。 - 前端 Editor 把 CSV Input 替换为 FailoverErrorTypeMultiSelect(基于 shadcn Popover + Checkbox + Badge 拼装),全选/清空、未知遗留值用红色 Badge + tooltip 提示删除;列表展示同样区分已知 label 与未知字符串。 - i18n 同步:英中文新增 SelectAll / ClearAll / RemoveAria / UnknownTooltip,Placeholder 改为选择式文案。 - 测试:服务层新增"拒绝未知 errorType / 历史含未知值的规则仍可匹配合法 evidence"两条;editor 测试将 MultiSelect mock 为按钮列表,断言数据契约。
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #187 +/- ##
==========================================
- Coverage 74.14% 74.05% -0.09%
==========================================
Files 145 147 +2
Lines 11048 11114 +66
Branches 3832 3846 +14
==========================================
+ Hits 8192 8231 +39
- Misses 1657 1682 +25
- Partials 1199 1201 +2
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
上一个 PR(#186)补齐了
UpstreamNoContentStreamError这条新错误类型后,复盘失败规则编辑界面,发现一个长期存在的可用性缺口:error_types字段是纯 CSV 文本输入,parseCsvList(...) as FailoverErrorType[]只是 TS 强转,运行时不做白名单校验。z.array(z.string().trim().min(1)),任何非空字符串都被接受。ruleMatchesEvidence用includes做严格匹配,evidence.errorType 始终是合法枚举值,所以拼错的规则永远不会命中,但不报错、不日志、不前端反馈。结果:用户随手写错一个 token,规则创建成功、列表显示"已启用"、但在生产里永远是僵尸规则。属于典型的 silent footgun。
改动
后端
src/lib/constants/failover-error-types.ts,作为FailoverErrorType的运行时单一来源:导出常量数组、failoverErrorTypeSchema(zod enum)、isKnownFailoverErrorType类型守卫。z.array(failoverErrorTypeSchema),拼错直接返回 400 并附允许值列表。assertValidRuleMatch增加 enum 校验作为第二防线(防御绕过 admin API 直接调 service 的路径)。ruleMatchesEvidence命中含未知值的历史规则时,以 per-rule-id 去重的方式log.warn一次,让运维通过日志感知到失效规则。前端
FailoverErrorTypeMultiSelect组件,基于 shadcn 的Popover + Checkbox + Badge拼装(项目当前没有 multi-select,shadcn 官方也不提供)。支持全选/清空,未知遗留值用红色 Badge + tooltip 显式提示删除。requestLogs.retryErrorType.*i18n)与未知字符串,未知值用红色 Badge。upstream-failure-rules-editor.tsx把 CSV<Input>替换为新组件,errorTypesstate 从string改为string[]。i18n
英中两份 messages 同步新增
failureRuleErrorTypesSelectAll/ClearAll/RemoveAria/failureRuleErrorTypeUnknownTooltip,placeholder 文案改为选择式。测试
errorType创建/更新;含未知值的历史规则仍可匹配合法 evidence(向后兼容)。error_types用例的期望从[]改为null(语义更清晰)。兼容性
filter(isKnownFailoverErrorType)剔除,符合后端 enum 校验。验证
pnpm lint通过pnpm exec tsc --noEmit通过pnpm test:run:147 文件 / 2489 通过 / 1 skippedTest Plan
{"error_types": ["xxxxx"]},确认返回 400。"http_500"这种历史未知值的规则,编辑界面应显示红色 Badge + tooltip。upstream failure rule contains unknown error types ...警告一次(同 rule 反复触发只 warn 一次)。