Skip to content

publish-drafts 可见性翻转中途失败时,已翻转的 app 从响应里整批消失 —— unhiddenApps 丢了,metadata:reloaded 也漏播 #5242

Description

@os-zhuang

发现于 #4754 的实现期(修 packages/runtime/src/domains/packages.ts 那处静默 catch 时读到)。未认领 —— 只是记录。观察类:操作幂等,重跑一次就好。

现象

POST /packages/:id/publish-drafts 的 ADR-0045 可见性翻转段(packages/runtime/src/domains/packages.ts),结构是:

const unhidden: string[] = [];
for (const app of apps) {
    if (app?.hidden === true && typeof app.name === 'string') {
        await protocol.saveMetaItem({ /* … hidden: false … */ });
        unhidden.push(app.name);
    }
}
if (unhidden.length > 0) result.unhiddenApps = unhidden;   // ← 只在循环全程无异常时才执行

unhiddenApps 的赋值在循环之后、try 之内。所以 5 个 app 里第 3 个 saveMetaItem 抛异常时:前 2 个确实已经翻转并落盘了,但 unhidden 数组随栈丢弃,result.unhiddenApps 压根不存在。

后果(两层,都不大)

  1. 响应少报了真实发生的事。 调用方看到的是「翻转失败」,看不到「其中 2 个已经成功」。属于 AGENTS.md「Route & surface ownership」第 4 条(machine-readable surfaces must not lie)的轻量版 —— 不是撒谎,是漏报。
  2. metadata:reloaded 对这 2 个 app 漏播。 紧跟其后的重绑定段读的正是这个字段:
...(((result as any)?.unhiddenApps ?? []) as string[]).map((n) => `app/${n}`)

字段缺失 → 这 2 个已经变可见的 app 不进 changed → boot-cached 的消费者(首当其冲是 automation engine)不重新同步它们,得等下一次重启。

为什么不塞进 #4754

#4754 的范围是「saveMetaItem 进词表 + 逐处判持久性丢失」,那处 catch 已按范本改成 error 并写清后果与修复动作。本条是同一段代码里的另一个缺陷(部分进度的报告丢失),和日志级别无关,改它要动 unhidden 的作用域和响应语义 —— 与该单的清账互不依赖,单独立卡。

建议做法

unhidden 提到 try 之外,并在 catch 里一并回填:成功多少就报多少。重跑本身是幂等的(已翻转的 app hidden !== true,循环会跳过),所以这纯粹是让报告与事实一致,不改变恢复路径。

关联

#4754(同一段 catch 的日志级别清账)、ADR-0045(publish 让包 live 且可见)、AGENTS.md「Route & surface ownership」第 4 条。

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions