Symptom
```
$ oma runtime list
fetch failed
$ oma runtime list # immediate retry
ID HOSTNAME OS STATUS ...
1de8655a… HGPV4Q1GKQ.local darwin/arm64 online ...
```
第一次失败、第二次立刻成功 —— transient network blip。但 CLI 抛的字符串就是 `fetch failed`,user 完全不知道是网络、auth、还是 server-side 问题,也不知道该不该 retry。
根因
`packages/cli/src/index.ts:208` `apiFetch`:
- 网络层 throw(`fetch` 自身 reject)→ 直接拿 `err.message`,常常就是 undici 的 "fetch failed",没有 cause / hostname / errno
- HTTP 错误(4xx/5xx)→ 没区分提示
修复方向
- 网络 throw 时把 `err.cause` 链一起打:`fetch failed (ENOTFOUND openma.dev)` / `fetch failed (ECONNRESET)` / `fetch failed (UND_ERR_HEADERS_TIMEOUT)` —— transient 一眼可辨
- 4xx/5xx 时透出 status + body:
- 401/403 → `Run \`oma auth login\` to re-authenticate`
- 5xx → `Server error (5xx), safe to retry`
- 加可选 retry-once for idempotent GET(`oma runtime list` / `oma whoami`),按 retry-after 或 1s 退避
不修不会怎样
发版越多、用户网络越多样,"fetch failed" 工单会一直来 —— 没有信息可分诊,每次都得 "再试一次"。
Out of scope
跟 0.3.0 发版无关,纯历史遗留。
Symptom
```
$ oma runtime list
fetch failed
$ oma runtime list # immediate retry
ID HOSTNAME OS STATUS ...
1de8655a… HGPV4Q1GKQ.local darwin/arm64 online ...
```
第一次失败、第二次立刻成功 —— transient network blip。但 CLI 抛的字符串就是 `fetch failed`,user 完全不知道是网络、auth、还是 server-side 问题,也不知道该不该 retry。
根因
`packages/cli/src/index.ts:208` `apiFetch`:
修复方向
不修不会怎样
发版越多、用户网络越多样,"fetch failed" 工单会一直来 —— 没有信息可分诊,每次都得 "再试一次"。
Out of scope
跟 0.3.0 发版无关,纯历史遗留。