fix(metadata-protocol): seed-loader 中「计为错误」的失败一律记 error,不再自相矛盾地记 warn (#4729) - #5001
Merged
Merged
Conversation
…#4729) `SeedLoaderService` pass-2 延迟引用回填的 catch 上方写着「this must be a reported, counted error, never a silent warning」,紧跟着的调用却是 `this.logger.warn`。计数是对的(`recordDeferredError` 进 `allErrors` ⇒ `success: false`),但日志级别与它矛盾 —— 而这一行是一次 seed 在宿主控制台上 留下的唯一痕迹,`warn` 正是 #4420 证明没人读的那一级。 - 该行提到 `error`,并按 AGENTS.md「Degradation log levels」补齐一条 error 该有的两件东西:**后果**(`<object>.<field>` 停在 NULL、行本身已种下所以 行计数一切正常、循环关系半写入)与**修复动作**(没有任何东西会重试,修掉 写入错误 —— 超出重试预算的瞬时故障,或某条 validation 规则否决了这次 update —— 之后重跑 seed)。 - 按同一判据(这次失败是否计入 `errors` / 是否让 `success` 变 false)盘完本 文件其余 `logger.warn`:另有五处「计为错误、日志 warn」一并提到 `error` —— 批量插入失败行、`cel` 表达式解析失败被丢弃的记录、两处 DROP 引用字段的非法 引用路径(行落了、关联没落,而行计数干净 —— framework#3932),以及顺序写 与 update 两处 catch。两处 DROP 路径的日志行另补后果与修复动作。 - 三处**维持 warn**并把审计结论写进注释:`Halting on first error`(控制流通知, 它所halt 的错误各自已在 error 级别报过)、`NODE_ENV` 无法判定(功能性、 fail-open 降级)、roll-up summary 重算失败(记录确实写入了;陈旧汇总列是否 属于 #4632 第二类另开 #4998 由维护者定夺)。 - 让门禁而不只是测试钉住这个接缝:回填写入抽成 `writeDeferredReference` (原写入在 `withTransientRetry` 闭包里,AST 扫描进不去),与 `writeRecord` 一同登记进 `scripts/check-durability-degradation-log-level.mjs` 的 `DURABILITY_CRITICAL_CALLEES`,这两处 catch 再被降级即 CI 红。 结果对象、API、schema 均无变化,变的只是级别与措辞。 另记录两处不在本单判据内的同文件发现:#4997(无 pass-2 时整条记录被丢弃却 一行日志都不打)、#4998(roll-up summary 陈旧值不计数、只记 warn)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NrmBxj8rK2uGCnh9aipjwX
…d-loader-loud-failure
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 3 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
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.
Fixes #4729
问题
packages/metadata-protocol/src/seed-loader.ts的 pass-2 延迟引用回填,catch 上方的注释白纸黑字写着这次失败 "must be a reported, counted error, never a silent warning",紧跟着的调用却是this.logger.warn。公允地说,它并不完全静默:
recordDeferredError(...)把它计入allErrors,success会变false。但日志行本身是一次 seed 在宿主控制台上留下的唯一痕迹,而warn正是 #4420 证明没人读的那一级 —— 后果(引用停在 NULL、循环关系半写入)则一个字都没说。计数与日志级别应当一致,这是本单的判据。改了什么
1. 主接缝提到
error,并补齐一条 error 该有的两件东西(AGENTS.md → "Degradation log levels",参照 #4823 / #4460 的文案形态):对象.字段在具名记录上停在NULL;行本身已经种下,所以每一个行计数都是干净的;循环关系处于 HALF-WRITTEN 状态,并点名它本该指向的目标对象.目标字段 = '自然键';err.message)并入同一行,读者不必再翻第二处。实际打出来长这样(测试里逐段断言):
2. 按同一判据盘完本文件其余
logger.warn。 判据取「这次失败是否进errors/allErrors(即是否让success变 false)」——buildResult里success = !(errors.length 大于 0 || totalErrored 大于 0),所以这条线是客观的。另有五处「计为错误、日志 warn」,一并提到error:cel表达式解析失败两处 DROP 引用的行额外补上后果与修复动作 —— 那正是 #3932 注释自己描述的形态:「行计数一切正常,损失只在别处看得见」,也就是 #4632 第二类的教科书样子。
3. 三处维持
warn,并把审计结论写进注释(免得下一个人再翻一遍):Halting on first error—— 控制流通知,它所 halt 的那些错误各自已在error级别报过;为同一批失败再喊一次正是 AGENTS.md 警告的「过度适用」;NODE_ENV无法判定(fix(seed): enforce Seed.env against the runtime environment #4836)—— 功能性、fail-open 降级;success仍为 true,不在本单判据内;陈旧汇总列是否属于 [convention] best-effort 降级导致"看起来正常、实则不持久"时不应记 warn——把 #4460 的点状修复定成规则 #4632 第二类另开 [metadata-protocol] seed-loader:roll-up summary 重算耗尽重试后只记 warn 且不计数 —— 落盘的汇总值与事实不符,seed 仍报 success: true #4998 由维护者定夺(改它会改变一次成功 seed 的输出,属于产品口径)。4. 让门禁钉住,而不只是测试。
pnpm check:durability-log-level按 callee 名匹配被try守护的接缝,且不下潜进嵌套函数体 —— 而原来的写入藏在withTransientRetry(() => ...)闭包里,AST 扫描根本看不见。于是把回填写入抽成writeDeferredReference,与writeRecord一同登记进DURABILITY_CRITICAL_CALLEES(各带一句「失败意味着什么」)。现在这两处 catch 若被降回warn,CI 直接红:durability-degradation.baseline.json保持空表(本 PR 不新增豁免)。测试
packages/metadata-protocol/src/seed-loader-deferred-failure.test.ts新增两条:error、消息点名audit_department.head_id、含stays NULL/HALF-WRITTEN/ 目标audit_worker.name/re-run the seed/ 原始 cause,第二/三个实参分别是Error与{ object, field },并断言该失败不再出现在warn上;同时确认它仍被计数(success: false、totalErrored大于 0、errors里有head_id);success: true,且logger.error/logger.warn一次都没被调用 —— 别把读者训练成跳过error。两处既有断言随之更新(
runtime/src/seed-loader.test.ts的写入失败、seed-loader-multi-value-reference.test.ts的 DROP 引用),后者顺带断言新的后果措辞。顺带记录(未在本 PR 修)
multiPass时「引用解析不了 ⇒ 整条记录丢弃」计为 error 却一行日志都不打。同一条链的更深一格,但不在本单「盘logger.warn」的判据内。两条都已在代码注释里留下指针。
验证
pnpm exec turbo run test --filter=@objectstack/metadata-protocol→ 34 files / 301 passed(合入main后重跑一次,仍 301)packages/runtime:seed-loader.test.ts+app-plugin.seed.test.ts+seed-datasets.test.ts→ 53 passed;packages/objectql两个 seed 用例 → 8 passedtsc --noEmit:metadata-protocol 改动前后同为 156 行输出(全是 ledger 记录的既有 TS2835/TS7006 噪声),seed-loader.ts零错误;runtime 无本文件相关错误lint、durability-log-level、startup-registry-verdict、init-service-contract、route-envelope、wildcard-fallthrough、error-code-casing、engine-double-contract、type-check-coverage、published-files、adr-anchors、slot-lookup、nul-bytes、doc-authoring、docs-audit-scope、role-word、org-identifier、authz-resolver、service-providers、objectui-changeset、release-notes、node-version、merge-drivercheck:i18n/check:i18n-coverage本地未跑通:两者都要求先做整仓 build(CI 里就排在 build 步骤之后,报错是osCLI 未构建),本 PR 不触碰任何 translation / 声明标签面changeset:
.changeset/seed-loader-loud-failure-log-level.md(@objectstack/metadata-protocolpatch)。🤖 Generated with Claude Code
https://claude.ai/code/session_01NrmBxj8rK2uGCnh9aipjwX