现象
openless-all/app/src/pages/Overview.tsx:57-60 初次挂载的两个 IPC 调用是裸 .then,没有 .catch:
useEffect(() => {
listHistory().then(setHistory);
getCredentials().then(setCreds);
}, []);
后端任一 handler 返回 Err(String) 时,promise 静默 reject,state 维持初始默认值,用户没有任何错误提示。
完整链路(UI → IPC → Rust handler)
| 调用 |
IPC 包装 |
Rust handler |
listHistory() |
src/lib/ipc.ts:188 invokeOrMock('list_history', …) |
commands.rs:539 list_history(…) -> Result<Vec<DictationSession>, String> |
getCredentials() |
src/lib/ipc.ts:159 invokeOrMock('get_credentials', …) |
commands.rs:150 get_credentials() -> CredentialsStatus |
失败路径
listHistory reject(history.json 读失败 / 反序列化失败)→ history 维持 [] → 概览页显示"今日字符 0、本周条形全 0、最近识别为空",和真正没有历史完全无法区分
getCredentials reject(vault 不可达 / IPC 异常)→ creds 维持初始默认(asrConfigured: false / llmConfigured: false)→ ProviderCard 永久显示"未配置",即使其实已配置;用户会被误导去重新填密钥
用户可见后果
- 概览数据看起来"是空的"——其实是后端读失败
- ProviderCard 错误地标"未配置",把已配好的用户引向重新填密钥的歧路
建议接受标准
不在范围
- 不引入全局 toast / 不改后端 handler 签名
- 历史数据本身的错误恢复(loss recovery)不在本 issue
现象
openless-all/app/src/pages/Overview.tsx:57-60初次挂载的两个 IPC 调用是裸.then,没有.catch:后端任一 handler 返回
Err(String)时,promise 静默 reject,state 维持初始默认值,用户没有任何错误提示。完整链路(UI → IPC → Rust handler)
listHistory()src/lib/ipc.ts:188invokeOrMock('list_history', …)commands.rs:539list_history(…) -> Result<Vec<DictationSession>, String>getCredentials()src/lib/ipc.ts:159invokeOrMock('get_credentials', …)commands.rs:150get_credentials() -> CredentialsStatus失败路径
listHistoryreject(history.json 读失败 / 反序列化失败)→history维持[]→ 概览页显示"今日字符 0、本周条形全 0、最近识别为空",和真正没有历史完全无法区分getCredentialsreject(vault 不可达 / IPC 异常)→creds维持初始默认(asrConfigured: false / llmConfigured: false)→ ProviderCard 永久显示"未配置",即使其实已配置;用户会被误导去重新填密钥用户可见后果
建议接受标准
.catch,失败时在对应卡片内显示 inline 错误(不阻塞整页)listHistory失败时显示可重试 placeholder不在范围