继续收敛模型配置读取错误
保留模型目录与选择器配置 IPC 的脱敏正文 更新模型选择器具体错误回归测试
This commit is contained in:
+10
-4
@@ -154,10 +154,16 @@ export function ConversationModelSelect({
|
||||
await waitForConfigWrite();
|
||||
if (selectionEpochRef.current !== epochAtRequest)
|
||||
return Boolean(selectedRef.current);
|
||||
const config = await invoke<GameCreatorAppConfigView>(
|
||||
'read_game_creator_app_config',
|
||||
).catch(() => null);
|
||||
if (!config) throw new ModelSelectionConfigError('读取客户端配置失败');
|
||||
let config: GameCreatorAppConfigView;
|
||||
try {
|
||||
config = await invoke<GameCreatorAppConfigView>(
|
||||
'read_game_creator_app_config',
|
||||
);
|
||||
} catch (error) {
|
||||
throw new ModelSelectionConfigError(
|
||||
`读取客户端配置失败:${visibleClientErrorMessage(error)}`,
|
||||
);
|
||||
}
|
||||
if (selectionEpochRef.current !== epochAtRequest)
|
||||
return Boolean(selectedRef.current);
|
||||
const saved = config.config.selectedModelId;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { resolveTauriInvoke } from '../app/tauri';
|
||||
import type { GameCreatorAppConfigView } from '../app/types';
|
||||
import { type ClientLlmModelCatalog, loadClientLlmModels } from './clientApi';
|
||||
import { visibleClientErrorMessage } from './errorReporting';
|
||||
|
||||
export type { ClientLlmModel, ClientLlmModelCatalog } from './clientApi';
|
||||
|
||||
@@ -32,7 +33,9 @@ async function loadEffectiveCatalog(epoch: number) {
|
||||
);
|
||||
} catch (error) {
|
||||
if (epoch === generation) cached = null;
|
||||
throw new LlmModelCatalogConfigError('读取客户端配置失败');
|
||||
throw new LlmModelCatalogConfigError(
|
||||
`读取客户端配置失败:${visibleClientErrorMessage(error)}`,
|
||||
);
|
||||
}
|
||||
if (epoch !== generation) throw new Error('模型配置已更新');
|
||||
const llm = config?.config.llm;
|
||||
|
||||
@@ -352,7 +352,7 @@ test('a failed save keeps submission unavailable', async () => {
|
||||
await screen.findByRole('button', { name: '对话模型' });
|
||||
fireEvent.click(screen.getByRole('button', { name: '对话模型' }));
|
||||
fireEvent.click(screen.getByRole('option', { name: '快速' }));
|
||||
await screen.findByText('模型选择保存失败');
|
||||
await screen.findByText('disk full');
|
||||
expect(onReady).toHaveBeenLastCalledWith(false);
|
||||
});
|
||||
|
||||
@@ -595,7 +595,7 @@ test('recovers the selector when reading the native config fails', async () => {
|
||||
invoke.mockRejectedValueOnce(new Error('config unreadable'));
|
||||
const onReady = vi.fn();
|
||||
render(<ConversationModelSelect disabled={false} onReady={onReady} />);
|
||||
await screen.findByText('读取客户端配置失败');
|
||||
await screen.findByText('读取客户端配置失败:config unreadable');
|
||||
await waitFor(() => expect(onReady).toHaveBeenLastCalledWith(false));
|
||||
|
||||
// 配置不可读时不能猜测官方路由;恢复读取后选项与刷新按钮重新可用。
|
||||
@@ -605,7 +605,9 @@ test('recovers the selector when reading the native config fails', async () => {
|
||||
expect(option.hasAttribute('disabled')).toBe(false);
|
||||
fireEvent.click(screen.getByRole('button', { name: '刷新模型列表' }));
|
||||
await waitFor(() => expect(onReady).toHaveBeenLastCalledWith(true));
|
||||
expect(screen.queryByText('读取客户端配置失败')).toBeNull();
|
||||
expect(
|
||||
screen.queryByText('读取客户端配置失败:config unreadable'),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
test('pre-send validation waits for an in-flight selection save', async () => {
|
||||
|
||||
@@ -89,3 +89,4 @@ DirectProject 回合失败在确认不是客户端内部不可归类故障时,
|
||||
- CC/Direct 工具桥的执行前后成果指纹、回执结算 JoinError/落盘失败,以及外部 MCP journal 的读取/JSON 行解析原先仍会被 `.ok()`、固定回执句或“无记录”吞掉;现分别保留指纹阶段、回执任务/落盘原因、journal 行号和底层正文,只有真实 `NotFound` 才视为空记录。
|
||||
- 外部 MCP `resources/read` 仍把已能返回具体原因的 Codex journal 读取错误 `unwrap_or_default()` 成空资源;现把读取失败按 MCP 错误响应返回,Direct 执行会话当前项目 canonicalize 也保留底层 I/O 正文。
|
||||
- Direct 交付终态读取原先把 `session.snapshot()` 锁/状态错误折叠成 `None`,上层继续显示“尚未确认交付完成”;现沿 `code-generation` 失败出口保留终态读取正文,并在已有回合失败时同时保留原始失败与终态读取失败。
|
||||
- 对话模型选择器读取 native 配置原先把 IPC/文件异常 `.catch(() => null)` 后只显示“读取客户端配置失败”;现通过统一可见错误脱敏出口保留具体正文,并保留配置不可读时不猜测模型路由的安全行为。
|
||||
|
||||
Reference in New Issue
Block a user