Skip to content

修复:无效 session 路由导致会话切换卡住 #24

@Kizunad

Description

@Kizunad

问题概述

当 URL 中包含当前目录下不存在的 session id 时,UI 在切换会话过程中会出现“卡住/假死”的体验。日志常见交替为 switch:fetch-sessionswitch:use-cached,且无效 session 请求返回 404。

复现步骤

  1. 打开类似 #/session/<invalid-session-id>?dir=/workspace/<project> 的链接
  2. 确认该 session id 在当前目录下不存在(GET /session/{id} 或消息接口返回 404)
  3. 通过侧边栏 / toast / 通知切换会话,或触发 SSE 重连
  4. 观察到会话切换反复抖动,界面表现为卡住

根因分析

  • 路由层会接受任意 #/session/{id},没有先做有效性校验
  • 会话加载失败时仅设置 loadState=error,没有清理无效路由
  • 无效 session id 持续留在 hash 中,并可被多个入口再次写回
  • 导致同一个无效 id 被反复请求,触发路由/状态来回切换

已实现修复方案

1)会话加载错误分类

文件:src/hooks/useSessionManager.ts

  • 扩展 onError 回调参数,增加元信息:{ sessionId, reason }
  • 识别 not found 类错误(404not_foundSession not found)并标记为 reason: 'session_not_found'

2)无效 session 的路由安全回退

文件:src/hooks/useChatSession.ts

  • useSessionManager 接入 onError
  • 对“当前路由会话”的 session_not_found 执行兜底:
    • messageStore.clearSession(sessionId)
    • resetPermissions()
    • resetPendingRequests()
    • replaceSession(null)(清理坏 session id,且不新增历史记录)

该方案可避免过期请求误伤新会话,并让 UI 立刻恢复可用。

为什么使用 replaceSession(null)

replaceSession(null) 使用 history.replaceState,会直接替换当前历史项并移除坏路由,不会额外污染浏览器历史;在此错误兜底场景下比 hash push 更稳妥。

验证结果

  • 修改文件 LSP 诊断:无 error
  • Typecheck:通过
  • Tests:通过(31 files / 60 tests)
  • Build:通过

备注

  • 当前仓库里存在的 lint warning 为既有问题,本次修复未新增 lint error
  • 本 Issue 仅跟踪“无效 session 路由导致卡住”问题,不涉及模型/Provider 配置问题

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions