Skip to content

os doctor 的 installed-package ledger 读取 catch 把「损坏」和「没装」当成同一件事 —— D5e 建议因此静默少报,并打出「clean」 #5412

Description

@baozhoutao

实施 #5403(给 config 分析的 catch 加上 error 绑定)时顺带核验发现;未在该 PR 里改 —— #5403 的判定面被限定为 config 分析那一个 catch 的输出,本条是另一处 catch、另一条检查的判定面。

事实

packages/cli/src/commands/doctor.ts:771-784(origin/main 4b61cf3):

/** Read the installed-package ledger without going through HTTP. Best-effort:
 *  a runtime that never installed anything simply has no directory. */
async function readInstalledPackageEntries(cwd: string): Promise<any[]> {
  try {
    const mod: any = await import('@objectstack/cloud-connection');
    const dir = path.join(cwd, mod.DEFAULT_INSTALLED_PACKAGES_DIR ?? '.objectstack/installed-packages');
    if (!fs.existsSync(dir)) return [];
    return new mod.LocalManifestSource(dir).list();
  } catch {
    return [];
  }
}

这个 catch 不带绑定,且覆盖了两件性质完全不同的事:

  1. import('@objectstack/cloud-connection') 解析不到 —— 可选包没装。注释写明了这一条,而且是对的:doctor 必须能在没有该包的 checkout 里跑完。
  2. new mod.LocalManifestSource(dir).list() 抛错 —— 目录存在(fs.existsSync(dir) 已经通过),但里面某个 manifest 损坏 / 不可读 / JSON 解析失败。

第 2 种被当成第 1 种处理,一律 return []。

后果

唯一的消费者是 ADR-0120 D5e 的 unique-scope 建议(findUnscopedGlobalUniques,同文件 792-815):它把「本项目 metadata 的 findings」和「ledger 里已装包的 findings」拼在一起。ledger 那一半返回空数组时,doctor 走的是 else 分支:

  ✓ Unique scope          No unconfirmed installation-wide uniques for this 'isolated' environment

也就是说,一个装了包、但 ledger 损坏的 isolated 环境,拿到的是一张干净的体检单,而不是「有一部分我没能读到」。这比报一条 warning 更糟:false PASS 会让操作者停止查看。

与 #5403 是同一族(诊断命令自己吞掉了唯一能解释状况的那个对象),但低一层:#5403 里被吞的是「检查跑不了」的原因,这里被吞的是「检查跑了一半」这个事实本身 —— 连「有东西没读到」都没说。也属于 #4801 / cloud#1020 的「诊断面与运行时不一致」家族。

复现路径(未在真机执行,静态可判)

前提:OS_TENANCY_POSTURE=isolated,.objectstack/installed-packages/ 存在且至少一个条目损坏(截断的 JSON、权限不可读)。预期得到上面那行 ✓ Unique scope,而不是任何提示。

可能的方向(供分诊,不预设)

备注

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions