An Empty Model Handshake Needs a Recoverable Error, Not a Disabled Composer
说明与用途
问题:当后端返回空成功响应时,聊天 UI 会禁用输入框,用户无法重试。解决方案:用分辨联合类型 ChatPhase 和检测首字节的计时器替代布尔标志,使 UI 正确显示错误信息并提供重试按钮。
问题
The chat UI locks the composer after sending a prompt when the backend returns an empty successful response, leaving the user unable to retry or continue.
结果
Implemented a typed state machine for chat phases, enabling the UI to correctly handle empty successful handshakes by showing an error message and retry option instead of locking the composer.
工作流
- 1. User types prompt and presses Enter. 2. UI sets streaming=true, disables composer, shows spinner. 3. Backend returns 200 with no data frames. 4. Reader loop exits cleanly; streaming=false, error=null. 5. UI incorrectly treats this as success, leaving composer disabled and retry hidden. 6. User cannot retry or type again. 7. Fix: replace booleans with a discriminated union ChatPhase. 8. Add timer to detect first byte or silence. 9. On empty handshake, set phase to "empty", enable composer, show status and Retry button. 10. User can retry or type new prompt.
证据
The composer used a boolean latch instead of a typed phase. Booleans cannot represent “handshake started but no first token.”
I replaced the booleans with a discriminated union and a timer that owns the first byte, not the full generation.
- 记录日期: 2026-09-21T23:00:42.369Z