refactor(framework): 移除 resolveBootstrap 下游兜底,立第二准则
- CLAUDE.md 新增「第二准则:数据源权威、唯一,下游不兜底」 - bootstrap 删除 fallbackServers 选项与 ?? DEFAULT_GAMESERVER 猜默认 - 无 server/gameserver、远程失败、解析不出地址 → 一律抛 ConfigFetchError 显式暴露 - 同步 guide + 两篇 spec(删 fallback/降级措辞) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -232,8 +232,8 @@ export const PROFILES: Record<string, DebugProfile> = {
|
||||
`resolveBootstrap` 决定 `servers`(一个 `ws://` 地址数组,交给 `NetClient` 轮询)的顺序:
|
||||
|
||||
1. **当前 profile 有 `server`** → 直接用它,**跳过远程配置抓取**(`local`/`lab` 这类直连档位走这条)。
|
||||
2. **否则**抓远程配置文件(profile 的 `gameserver`,没有就用 `DEFAULT_GAMESERVER`),用 `getParam` 取出连接参数,`resolveServers` 组装候选列表。
|
||||
3. 远程抓取失败或解析不出地址时:若调用方传了 `fallbackServers` 则降级使用;否则抛 `ConfigFetchError`(交由上层重试,重连本身归 `NetClient`)。
|
||||
2. **否则**抓 profile 的 `gameserver` 远程配置文件,用 `getParam` 取出连接参数,`resolveServers` 组装候选列表。
|
||||
3. **不兜底**(CLAUDE.md 第二准则):profile 既无 `server` 又无 `gameserver`、远程抓取失败、或解析不出任何地址——一律抛 `ConfigFetchError` **显式暴露**,不猜默认、不降级。重试/重连归 `NetClient`,不在本层造兜底轮子。
|
||||
|
||||
`resolveServers` 取的连接参数键(**逐字一致**原工程,按此优先级):
|
||||
|
||||
@@ -308,7 +308,6 @@ interface BootstrapOptions {
|
||||
search: string; // location.search(如 '?profile=local')
|
||||
fetcher: ConfigFetcher; // 远程配置抓取;生产传 new HttpConfigFetcher()
|
||||
isNative: boolean; // 环境判定:原生 WebView=true,H5/浏览器=false(由调用方算)
|
||||
fallbackServers?: string[];// 远程失败/无地址时降级
|
||||
cacheBust?: () => string; // 防缓存串注入(默认 String(Date.now()))
|
||||
}
|
||||
|
||||
@@ -318,7 +317,7 @@ interface BootstrapResult {
|
||||
rawConfig: RemoteConfig | null; // 直连档位为 null
|
||||
profile: DebugProfile;
|
||||
mode: 'debug' | 'release'; // 透传入参 mode
|
||||
isDebugger: boolean; // 是否开启收发包日志(debug 模式 + profile.isDebugger)
|
||||
isDebugger: boolean; // 是否开启收发包日志(= mode === 'debug')
|
||||
}
|
||||
|
||||
function resolveBootstrap(opts: BootstrapOptions): Promise<BootstrapResult>;
|
||||
@@ -344,7 +343,6 @@ async function startup() {
|
||||
search: location.search,
|
||||
fetcher: new HttpConfigFetcher(),
|
||||
isNative: href.indexOf('index.html') > -1, // 等价旧 Logic.isH5Version() 反向
|
||||
fallbackServers: [], // 可选:填应急地址
|
||||
});
|
||||
|
||||
const net = new NetClient({
|
||||
@@ -435,9 +433,9 @@ npm run typecheck:framework # 类型检查(tsc --noEmit)
|
||||
|
||||
在 `PROFILES` 里加一个档位(见 [§5](#5-调试-profiles) 的 `lab` 例子),用 `?profile=lab`。
|
||||
|
||||
### E. 远程配置服挂了也要能调
|
||||
### E. 想绕开远程配置服直连某地址
|
||||
|
||||
给 `resolveBootstrap` 传 `fallbackServers: ['ws://<应急地址>']`,抓取失败时自动降级。
|
||||
加一个带 `server` 的 profile(同 D 的 `lab` 例子)用 `?profile=lab` 直连——这是把"应急地址"写进**权威来源**(profile),而不是让 `resolveBootstrap` 兜底。远程配置服真的挂了,就是显式 `ConfigFetchError`,去修配置服或临时切到直连 profile,不在代码里降级(CLAUDE.md 第二准则)。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -93,7 +93,6 @@ export interface BootstrapOptions {
|
||||
search: string; // location.search(测试可注入)
|
||||
fetcher: ConfigFetcher; // 远程配置抓取(测试注入 fake)
|
||||
isNative: boolean; // 环境判定结果(URL 含 index.html → true)
|
||||
fallbackServers?: string[]; // 远程失败时降级
|
||||
}
|
||||
export interface BootstrapResult {
|
||||
identity: ChannelIdentity;
|
||||
@@ -134,7 +133,7 @@ export function resolveActiveProfile(search: string): DebugProfile;
|
||||
|
||||
## 6. 错误处理
|
||||
|
||||
- 远程抓取失败:无 `fallbackServers` 时抛 `ConfigFetchError`,交调用方重试(重连归 net,不在本层重复造轮子);有 fallback 则降级使用;
|
||||
- 远程抓取失败 / 解析不出任何地址 / profile 既无 server 又无 gameserver:一律抛 `ConfigFetchError` **显式暴露**,不猜默认、不降级(CLAUDE.md 第二准则)。重试/重连归 net,不在本层造兜底;
|
||||
- `getParam`:某层匹配不到 → 返回已找到的最具体值或顶层 `data[key]`,最终可能 `null`(忠实原语义);
|
||||
- 原生 settings 缺失:`try/catch` → source 返回 `{}`(不覆盖),等价原 `try/catch return ""`;
|
||||
- 远程 txt JSON 解析失败:抛 `ConfigParseError`。
|
||||
|
||||
@@ -57,7 +57,6 @@ export interface BootstrapOptions {
|
||||
search: string;
|
||||
fetcher: ConfigFetcher;
|
||||
isNative: boolean;
|
||||
fallbackServers?: string[];
|
||||
cacheBust?: () => string;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user