fix(cli): narrow update-check error classification - #7431
Conversation
Corrected tmux E2E Test ReportImportant This replaces the earlier report's evidence boundary. The earlier Before/After used explicit Result
Environment: macOS 15.1.1, Node.js v22.22.0, tmux 3.5a, real interactive Qwen TUI at 200×50. Each run used an isolated empty Scenario 1: real startup background DNS failureThis was a normal interactive startup, not env QWEN_HOME=<isolated-dir> npm_config_registry=http://this-host-does-not-exist-zzz.invalid node dist/cli.js --safe-mode
Before: After: This is the reproduced user-visible improvement: Node 22's nested Scenario 2: real global-npm timeout controlEach revision was installed into an isolated temporary npm global layout and launched through the real production launcher. A local registry accepted the real package GET request and intentionally never responded.
Observed on both revisions: The local server recorded one package request from each run. The requested baseline Verification
Screenshot provenancemacOS screen-capture permission was unavailable to the test process. Each PNG is visibly labeled and was rendered without content changes from its corresponding real |
|
Thanks for the PR! Template looks good ✓ Problem: Observed bug with evidence. Post-merge tmux testing against a real temporary global npm installation showed the Direction: Aligned — this narrows #7428 to what was actually reproduced, removing speculative branches. No CHANGELOG reference needed; this is a follow-up fix to an already-merged PR. Size: Not applicable — no core paths touched. 2 files, 12 additions / 34 deletions (net -22 lines). Approach: Scope feels right. Every edit serves the stated goal: Moving on to code review. 🔍 中文说明感谢贡献! 模板完整 ✓ 问题: 已观测到的 bug,有证据。合并后的 tmux 测试使用真实的临时全局 npm 安装,证明 方向: 对齐——将 #7428 收窄到实际复现的部分,删除推测性分支。 规模: 不适用——未触及核心路径。2 个文件,+12 / -34(净减 22 行)。 方案: 范围合理。每处改动都服务于目标: 进入代码审查 🔍 — Qwen Code · qwen3.7-max Reviewed at |
Code ReviewIndependent proposal: given the problem (killed/SIGTERM is dead code because the outer Correctness:
No critical blockers. No convention violations. TestingUnit tests: 40/40 pass ( Direct module verification (built PR code, exercising All classifications match the PR's stated intent. The tmux: not available on this CI runner ( 中文说明代码审查独立方案: 鉴于问题(killed/SIGTERM 是死代码,因为外层 正确性:
无关键阻塞。无规范违反。 测试单元测试: 40/40 通过。 直接模块验证(构建 PR 代码):所有分类符合 PR 声明的意图。 tmux: 此 CI 运行器不可用。直接模块验证已端到端测试了分类逻辑。 — Qwen Code · qwen3.7-max Reviewed at |
|
Confidence: 5/5 — clean across every stage; would merge without hesitation. This is a textbook follow-up: #7428 added speculative branches (killed/SIGTERM, ETIMEDOUT-as-timeout) that post-merge tmux testing proved unnecessary. This PR narrows to what was actually reproduced, and the result is 22 fewer lines of code that are easier to reason about. The Unit tests 40/40, direct module verification confirms all six classification paths. No concerns. 中文说明置信度:5/5 — 每个阶段都干净;毫不犹豫地合并。 这是一个标准的后续修正:#7428 添加了推测性分支(killed/SIGTERM、ETIMEDOUT 归为 timeout),合并后的 tmux 测试证明它们不必要。本 PR 收窄到实际复现的部分,结果是少了 22 行更易理解的代码。 单元测试 40/40,直接模块验证确认所有六个分类路径。无顾虑。 — Qwen Code · qwen3.7-max Reviewed at |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
No issues found. LGTM! ✅
— qwen3.7-max via Qwen Code /review
doudouOUC
left a comment
There was a problem hiding this comment.
No issues found. LGTM! ✅
— qwen3.7-max via Qwen Code /review




What this PR does
This narrows the update-check classifier change merged in #7428 to the behavior reproduced through the complete user path. It keeps direct
error.causeinspection for Node 22 fetch failures, removes thekilled/SIGTERMchild-process special case, and restoresETIMEDOUTto the existing offline bucket.Why it's needed
Post-merge tmux testing exercised a real temporary global npm installation against a local registry that accepted requests but never responded. Both the #7409 baseline and #7428 rendered
registry did not respond within 5s. The outerfetchInfoWithTimeoutand inner npm child-process timeout both use 5000 ms; the outer typed timeout surfaces before the killed child's rejection propagates. The direct child-process unit test bypassed that real wrapper and therefore did not demonstrate the claimed user-visible fix.The nested fetch cause remains a real issue: Node 22 reports DNS failure as
TypeError: fetch failedwithENOTFOUNDonerror.cause.code. A real startup TUI run changes fromregistry erroron the #7409 baseline toregistry unreachablewith that fix.Reviewer Test Plan
How to verify
cd packages/cli && npx vitest run src/ui/utils/updateCheck.test.ts; all 40 tests should pass.npm_config_registry=http://this-host-does-not-exist-zzz.invalid; the background warning should reportregistry unreachable.registry did not respond within 5s.Evidence (Before & After)
The corrected real-startup tmux evidence and the no-differential global-npm timeout control are posted as a separate PR comment.
Tested on
Environment (optional)
macOS 15.1.1, Node.js v22.22.0, tmux 3.5a. Windows and Linux are left to CI.
Risk & Scope
Linked Issues
Follow-up to #7428
Related to #7423 and #7409
中文说明
本 PR 做了什么
本 PR 将 #7428 的更新检查分类改动收窄到完整用户路径中真实复现的部分:保留 Node 22 fetch 失败的直接
error.cause检查,删除killed/SIGTERM子进程特判,并把ETIMEDOUT恢复到原有的离线分类。为什么需要
合并后的 tmux 测试使用真实的临时全局 npm 安装,并连接到一个接受请求但永不响应的本地 registry。#7409 baseline 与 #7428 都显示
registry did not respond within 5s。外层fetchInfoWithTimeout与内层 npm 子进程超时都使用 5000 ms,外层类型化超时会在被杀子进程的 rejection 传播前返回。原来的直接子进程单元测试绕过了真实包装层,不能证明所声称的用户可见修复。嵌套 fetch cause 则是真实问题:Node 22 将 DNS 失败报告为
TypeError: fetch failed,并把ENOTFOUND放在error.cause.code。真实启动 TUI 从 #7409 baseline 的registry error正确变为registry unreachable。验证
风险与范围
恢复 #7409 原有 timeout 分类,已复现的 nested fetch 修复保持不变。递归/聚合 cause 遍历以及 Windows/Linux 手动 TUI 验证不在本 PR 范围内。