Repository navigation
Conversation
Mars-Sea#110 保存设置失败时的提示不可诊断 - `RemoteSettingsScope` 记住最近一次被拒的宿主原文(`lastMutationFailure()`), 被拒的写入不再把 `error.message` 丢在 `mutate()` 里。 - `SettingsWriteResult` 新增可选 `configError`,`commit()`/`configure()`/`drain()` 三条失败路径都把它带到 UI;`SettingsScope` 接口加可选方法,旧的测试桩不受影响。 - `settingsWriteNotice()` 追加「宿主返回:…」(原始异常超过 200 字符截断), 只有看起来是瞬时的原因(锁超时、`PROFILE_BUSY`、`ETIMEDOUT` 等)才补一句「稍后重试通常能成功」。 - 英文 / 中文的 `writeConfigUnconfirmed` 去掉会误导的「密钥未写入」——保存失败与密钥 是否写入是两件事,真实原因现在由新增的两条文案给出。 Mars-Sea#111 带路径前缀的 apiBase 一定探活误报,断连提示不含目标 host:port - `probeCommandCode()` 不再 `new URL('/', apiBase)` 打回 host root,改为新增的 `probeTargetOf(apiBase)`:保留路径前缀、补尾斜杠;真实模型请求本来就是 `${apiBase}${path}` 字符串拼接,前缀反代只在 prefix 内路由。 - `getUsage()` 的失败记录从端点 path 改成 `${base}${path}`,`detail` 里因此带上 完整的 `scheme://host:port` 与反代前缀,端口一变就能从提示里看出来。 - `usageNetworkHint` / `errorNetworkHint` 说明每条失败都会列出它尝试的地址。 两处行为变化都由新测试覆盖(service-probe 3 项、adapter 1 项、settings 2 项、 settings-scope 1 项),全量 `npm test` 1148 项通过。
|
谢谢这份 PR,也谢谢前面两条 issue 的复现——诊断是准的,两个问题都成立。 当前状态:这两条 issue 的修复已随 v0.16.3 发布(Release),#110、#111 也已在 issue 下回复。因此本 PR 与已发布的实现重叠,分支又与当前 与已发布实现的两处差异1. 探活目标: 你保留前缀探 base 根,能解决 bili 这类「整站映射」反代。我们改探真实端点,是因为还有两类情况探根解决不了:
代价是判定语义从「镜像官方状态页 monitor」变成「本机到鉴权层是否可达」,所以 401/403 也计为可达(探活刻意不带凭据,401 就是预期回答),404/429/5xx 仍判异常。这个口径写进了模块注释与《决策记录》第十一章。 2. 用量失败串:路径 + 目标 origin,另加中文原因 你拼完整 URL,信息更全;已发布版本改为 3. 保存失败原文:随返回值透传,而不是 scope 上的状态 你的 你这里做得更好、但这次没进版本的两点
这两点欢迎单独开 PR(基于最新 我们的流程失误这个 PR 在 2026-10-31T08:40Z 就开了,我们在 14:45Z 发布了同一批修复——中间没检查过 PR 列表,只看了 issue,造成了重复劳动。已把「接 issue 时查一次 PR、发版前再查一次,已有 PR 不得静默取代」写进仓库的 再次感谢。 |
关联 issue
改了什么
#110 保存设置失败时的提示不可诊断
原先
RemoteSettingsScope.mutate()只把结果压成'conflict' | 'failed',宿主返回的原文在那一行就被丢掉了,UI 于是只能显示固定的「配置提交未获确认;密钥未写入」。真实原因(例如atomic-write: timed out waiting for the writer lock at <DSH_HOME>/profiles/web/package.json.lock)永远到不了用户眼前。RemoteSettingsScope新增private mutationFailure与公共lastMutationFailure():被拒时记住response.error?.message,下一次成功写入清空。SettingsScope接口加可选lastMutationFailure?()(旧测试桩不受影响);createSettingsScope()的返回字面量显式转发该方法。SettingsWriteResult新增可选configError;commit()改为返回{ confirmation, failure },四条失败路径(不可写 / 宿主没有原子 mutate / 待提交字段变了 / scope 报错)各自给出原因,drain()的 catch 用readableErrorText(error)。settingsWriteNotice()追加一条writeConfigFailedDetail(宿主返回:{error},超过 200 字符截断);只有看起来瞬时的原因(PROFILE_BUSY、EAGAIN/EBUSY、ETIMEDOUT、writer lock、timed out等)才补writeConfigRetryable。writeConfigUnconfirmed去掉误导性的「the key was not written」:保存失败与密钥是否写入是两件事。#111 带路径前缀的 apiBase 一定探活误报;断连提示不含目标 host:port
probeCommandCode()原先是new URL('/', options.apiBase),把所有路径前缀折成 host root。真实模型请求是字符串拼接${apiBase}${path},http://127.0.0.1:18797/bili/https://api.commandcode.ai这类前缀反代只在 prefix 内路由,探到根路径必然 404 并被判成http-error。现在改用新增的probeTargetOf(apiBase):保留路径前缀、补尾斜杠,探活目标就是配置的 base 本身。getUsage()的失败串从端点 path 改成${base}${path},于是detail里带完整的scheme://host:port与反代前缀——端口从 18797 漂到 18798 时,提示直接给出试过的地址,而不再只是「所有请求都没有到达服务端」。usageNetworkHint/errorNetworkHint两种语言的文案改为说明每条失败都会列出它尝试的地址。验证
npm run typecheck通过。npm test全量 1148 项通过(新增 7 项:probeTargetOf单元、path prefix、reverse-proxy prefix、getUsage失败记录保留前缀、lastMutationFailure保留/清空、提示带宿主原文、过长原文截断)。npm run build成功,lib/构建产物按仓库惯例用git add -f一并提交。没有动的
package.json版本号与CHANGELOG.md留给发版流程。