Skip to content

os doctor 对非法 OS_TENANCY_POSTURE 退出码 0 并报告「环境功能正常」—— 抛错被 config 分析的宽 catch 吞成一句「Could not load config」 #5382

Description

@baozhoutao

发现于 #5359(serve 的 posture 闸门,PR #5381)实施过程中的顺带核验;本单只记录,不在该 PR 里改(那单的文件面被限定为 packages/cli/src/commands/serve.ts)。

与 #5359 是同一形状、不同命令,但不是它的子集:#5359 的完成范围只覆盖 serve.ts,本单的修复点在 doctor.ts,两者可独立进行。

现象

一个 OS_TENANCY_POSTURE 拼错、根本无法启动的环境,os doctor 报告它「functional」并 exit 0:

$ OS_TENANCY_POSTURE=bogus os doctor
  …
  ⚠ Could not load config for analysis (config checks skipped)

⚠️  Environment is functional but has some warnings.
   Run with --verbose to see fix suggestions.

EXIT=0

全程没有任何一个字提到 OS_TENANCY_POSTURE。而同一个环境下 os serve 是会拒绝启动的(退出码 1)。

成因(origin/main @ 2f6516e)

packages/cli/src/commands/doctor.ts:688:

        if (postureGatesGlobalUniques(resolveTenancyPosture())) {

这行位于 config 分析那个很宽的 try 内,其 catch 在 doctor.ts:740-743:

      } catch {
        printWarning('Could not load config for analysis (config checks skipped)');
        hasWarnings = true;
      }

resolveTenancyPosture()(packages/types/src/env.ts:145)对无法识别的值抛错,这个抛错被上面这个 catch 接住,转述成「配置载不进来」——归因错了(配置本身没问题),并且只记为 warning,所以最终退出码是 0。

doctor.ts:294(findUnscopedGlobalUniques() 内的 resolveTenancyPosture())在同一个 try 的覆盖下,同理。

为什么值得修

这是「declared ≠ enforced」落在诊断面上,而且落在最糟的位置:os doctor 正是运维在 serve 起不来之后会去跑的那个命令。它此刻回答「环境功能正常」,等于把排查引向别处。#4801 / cloud#1020 已经为「诊断面与运行时不一致」付过一次账,这次是诊断面与另一个 CLI 命令不一致。

另外 exit 0 意味着任何把 os doctor 放进 CI/健康检查的地方,都不会因为这个配置错误变红。

建议方向(未实现,供 triage)

两条都不在本单决定:

  1. 与 PR fix(cli): 非法 OS_TENANCY_POSTURE 在 serve 最开头被显式拒绝,不再伪装成 AuthPlugin 加载失败 (#5359) #5381 给 serve 加的闸门同构 —— 在 doctor 早期、宽 catch 之外解析一次 posture,非法值直接以带处方的文案报 error 并让 hasErrors = true(doctor 的语义是「报告」而非「拒绝」,所以大概率不该 process.exit(1),而是走它自己的 error 汇总)。
  2. 更窄的做法:只把 resolveTenancyPosture() 从那个 try 里提出来。

倾向 1:doctor 的价值就在于把 env 层面的问题指名道姓说出来,而不是让它以「config 载不进来」的形态糊过去。

现状证据

packages/cli 下没有测试钉 doctor 在非法 posture 下的行为(#5359 之前 packages/cli 对该变量零测试;PR #5381 新增的 serve-tenancy-posture-gate.test.ts 只覆盖 serve)。

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