Skip to content

MetadataProtocol.listCommits 把 commit store 读不到答成 [] —— ADR-0067 时间线上「无历史」与「读不到」不可分辨(零日志,JSDoc 里写着这是设计) #5980

Description

@hotlong

发现于 #5186(为「读接缝把故障答成空值」这一族新增闸门)实施期,由新规则在 packages/metadata-protocol 扫出;不在该单文件面内(#5186 是纯 scripts/ 闸门单,不改被扫包),故单独立卡并已作为 baseline 条目记录在 scripts/durability-read-invention.baseline.json

现象

packages/metadata-protocol/src/protocol.tslistCommits()(约 9720–9745 行,以 origin/main 为准):

/**
 * List the commit timeline for a package, newest-first (ADR-0067). Returns
 * [] if the commit store is unavailable.        ←← JSDoc 自己就这么写
 */
async listCommits(request): Promise< [] > {
  try {
    const rows = (await this.engine.find('sys_metadata_commit', { where,})) as any[];
    // … 映射 + 按 createdAt 倒序 …
    return mapped;
  } catch {
    return [];
  }
}

catch 里:没有任何日志、没有 rethrow、没有按错误类型区分

为什么这是缺陷而不是设计

这是 ADR-0110 D3(miss 与 outage 是两个意义相反的事实,消费方不得把其中一个读成另一个)在 ADR-0067 提交时间线上的违反,与 #5108DatabaseLoader 修的、#5532同一个文件getMetaItems 修的是同一形状:

  • 存储读不到 → 调用方看到「这个 package 没有任何提交历史」;
  • 「没有提交历史」与「有 12 次提交但库连不上」在返回值上完全一致;
  • 一行日志都没有,整条链路上没有任何地方说过这次读失败了。

后果面朝向 revert:提交时间线是 revertCommit 的选择面。历史被答成空的那一刻,UI 上「无可回滚项」,而实际上有——一次故障期间的运维判断会因此做反。

同一个文件几千行之上已经有了正确形状的处方:rethrowUnlessMetadataStoreUnprovisioned()(#5532 引入),它问 isMissingTableError,良性放行、其余包成 503 上抛。listCommits 只是没走它。

修法

} catch (error) {
  this.rethrowUnlessMetadataStoreUnprovisioned(error);   // 良性(表未建)放行
  return [];                                            // 首启确实没有提交
}

isMissingTableError 与该 guard 在本文件里都已经在用,无新依赖。

验收

  • sys_metadata_commit 未 provision(首启)→ 仍返回 [],不抛、不噪;
  • 驱动报连接错误 / 超时 / 权限失败 → 上抛(503 信封),调用方能把 outage 与 miss 分开;
  • 更新 JSDoc:删掉「Returns [] if the commit store is unavailable」这句(它现在描述的是缺陷);
  • 修好后删除 scripts/durability-read-invention.baseline.json 里的 packages/metadata-protocol/src/protocol.ts::listCommits 条目(shrink-only,条目失效即红)。

关联

#5186(新增本族闸门,本卡由它扫出)、#5532(同文件、同处方,getMetaItems)、#5108(同族,DatabaseLoader 五处读)、#5841(同文件另一处,退休手抄的 /no such table/i)、#4825 / #4728(同族)、ADR-0110 D3、ADR-0067、AGENTS.md「Absence must be loud」。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions