Files
qwen-code/packages/vscode-ide-companion/docs-tmp/DEBUGGING_DOUBLE_LOGIN.md
yiliang114 732220e651 wip(vscode-ide-companion): 实现 quick win 功能
- 将 WebView 调整到编辑器右侧
- 添加 ChatHeader 组件,实现会话下拉菜单
- 替换模态框为紧凑型下拉菜单
- 更新会话切换逻辑,显示当前标题
- 清理旧的会话选择器样式
基于 Claude Code v2.0.43 UI 分析实现。
2025-11-19 00:16:45 +08:00

9.3 KiB
Raw Blame History

🐛 调试"两次登录"问题指南

问题描述

用户反馈:打开 Qwen Code Chat UI 时,似乎一定会触发两次登录。

已实施的修复

1. 添加详细日志追踪

QwenAgentManager.tsauthenticateWithRetry 方法中添加了详细日志:

private async authenticateWithRetry(authMethod: string, maxRetries: number) {
  const timestamp = new Date().toISOString();
  const callStack = new Error().stack;
  console.log(`[QwenAgentManager] 🔐 AUTHENTICATION CALL STARTED at ${timestamp}`);
  console.log(`[QwenAgentManager] Auth method: ${authMethod}, Max retries: ${maxRetries}`);
  console.log(`[QwenAgentManager] Call stack:\n${callStack}`);

  // ... 认证逻辑
}

作用:每次调用 authenticateWithRetry 都会打印时间戳和调用栈,方便追踪是否有重复调用。

2. 修复 agentInitialized 标志未重置问题

WebViewProvider.ts 中添加了 resetAgentState 方法:

resetAgentState(): void {
  console.log('[WebViewProvider] Resetting agent state');
  this.agentInitialized = false;
  this.agentManager.disconnect();
}

extension.tsclearAuthCache 命令中调用:

vscode.commands.registerCommand('qwenCode.clearAuthCache', async () => {
  await authStateManager.clearAuthState();

  // Reset WebView agent state to force re-authentication
  if (webViewProvider) {
    webViewProvider.resetAgentState();
  }

  vscode.window.showInformationMessage(
    'Qwen Code authentication cache cleared. You will need to login again on next connection.',
  );
});

作用:确保清除缓存后,下次打开 Chat UI 会正确地重新初始化和认证。

🔍 如何测试和诊断

步骤 1: 清除现有缓存

# 在 VSCode 中执行命令
Cmd+Shift+P (macOS) 或 Ctrl+Shift+P (Windows/Linux)
输入: "Qwen Code: Clear Authentication Cache"

步骤 2: 打开输出面板

View → Output → 选择 "Qwen Code Companion"

步骤 3: 打开 Chat UI 并观察日志

Cmd+Shift+P → "Qwen Code: Open Chat"

步骤 4: 分析日志

正常情况(只认证一次)

[WebViewProvider] Starting initialization, workingDir: /Users/xxx/workspace
[WebViewProvider] Connecting to agent...
[QwenAgentManager] Reading local session files...
[QwenAgentManager] Creating new session...
[QwenAgentManager] 🔐 AUTHENTICATION CALL STARTED at 2025-11-17T10:00:00.000Z
[QwenAgentManager] Auth method: qwen-oauth, Max retries: 3
[QwenAgentManager] Call stack:
    at QwenAgentManager.authenticateWithRetry (/path/to/QwenAgentManager.ts:206)
    at QwenAgentManager.connect (/path/to/QwenAgentManager.ts:162)
    ...
[QwenAgentManager] 📝 Authenticating (attempt 1/3)...
[ACP] Sending authenticate request with methodId: qwen-oauth
[ACP] Authenticate successful
[QwenAgentManager] ✅ Authentication successful on attempt 1
[QwenAgentManager] New session created successfully
[AuthStateManager] Auth state saved
[WebViewProvider] Agent connected successfully

关键点

  • 只有 一个 "🔐 AUTHENTICATION CALL STARTED"
  • 认证成功后立即创建 session
  • 整个流程顺利完成

异常情况(认证多次)

[QwenAgentManager] 🔐 AUTHENTICATION CALL STARTED at 2025-11-17T10:00:00.000Z
[QwenAgentManager] Call stack:
    at QwenAgentManager.authenticateWithRetry (/path/to/QwenAgentManager.ts:206)
    at QwenAgentManager.connect (/path/to/QwenAgentManager.ts:162)  ← 第一次调用
[QwenAgentManager] 📝 Authenticating (attempt 1/3)...
[QwenAgentManager] ✅ Authentication successful on attempt 1
[QwenAgentManager] Session creation failed...
[QwenAgentManager] 🔐 AUTHENTICATION CALL STARTED at 2025-11-17T10:00:05.000Z
[QwenAgentManager] Call stack:
    at QwenAgentManager.authenticateWithRetry (/path/to/QwenAgentManager.ts:206)
    at QwenAgentManager.connect (/path/to/QwenAgentManager.ts:184)  ← 第二次调用(缓存失效重试)
[QwenAgentManager] 📝 Authenticating (attempt 1/3)...

关键点

  • 两个 "🔐 AUTHENTICATION CALL STARTED"
  • 第一次认证成功
  • Session 创建失败
  • 触发了缓存失效重试(第 184 行)

🤔 可能的原因分析

情况 1: 缓存有效但 Token 过期

触发条件

  • 本地缓存显示已认证
  • 跳过认证,直接创建 session
  • Session 创建失败(因为服务器端 token 已过期)
  • 触发缓存失效逻辑,清除缓存并重新认证

代码位置 QwenAgentManager.ts:173-194

try {
  await this.newSessionWithRetry(workingDir, 3);
} catch (sessionError) {
  // 如果使用了缓存needsAuth = false但 session 创建失败
  if (!needsAuth && authStateManager) {
    console.log(
      '[QwenAgentManager] Session creation failed with cached auth...',
    );
    await authStateManager.clearAuthState();

    // 第二次认证!
    await this.authenticateWithRetry(authMethod, 3);
    await authStateManager.saveAuthState(workingDir, authMethod);
    await this.newSessionWithRetry(workingDir, 3);
  }
}

是否正常

  • 这是正常的设计,用于处理缓存有效但服务器 token 过期的情况
  • ⚠️ 但如果 每次 都触发这个逻辑,说明有问题

情况 2: 认证重试(单次调用的多次尝试)

触发条件

  • 网络不稳定
  • 认证失败,自动重试

日志特征

[QwenAgentManager] 🔐 AUTHENTICATION CALL STARTED  ← 只有一个
[QwenAgentManager] 📝 Authenticating (attempt 1/3)...
[QwenAgentManager] ❌ Authentication attempt 1 failed
[QwenAgentManager] ⏳ Retrying in 1000ms...
[QwenAgentManager] 📝 Authenticating (attempt 2/3)...
[QwenAgentManager] ✅ Authentication successful on attempt 2

是否正常

  • 这是正常的,这是单次认证调用的重试机制
  • 用户可能看到多次浏览器弹窗,但这是预期行为

情况 3: OAuth 流程本身需要多次交互

可能原因

  • Qwen CLI 的 OAuth 实现可能需要:
    1. 第一步获取授权码authorization code
    2. 第二步交换访问令牌access token

如何确认

  • 如果日志只显示 一个 "🔐 AUTHENTICATION CALL STARTED"
  • 但浏览器弹出了 两次 授权页面
  • 那么是 CLI 的 OAuth 流程设计,不是扩展的问题

情况 4: agentInitialized 标志失效

触发条件

  • 每次打开 Chat UI 都重新初始化
  • agentInitialized 没有正确保持为 true

如何确认

第1次打开:
[WebViewProvider] Starting initialization...  ← 正常

第2次打开不关闭 WebView:
[WebViewProvider] Starting initialization...  ← 异常!应该是 "Agent already initialized"

修复状态

  • 已修复(添加了 resetAgentState 方法)

📋 测试清单

请按照以下步骤测试,并记录日志:

测试 1: 首次登录

1. 清除缓存: Cmd+Shift+P → "Clear Authentication Cache"
2. 重启 VSCode Extension Host (F5 重新调试)
3. 打开 Chat UI: Cmd+Shift+P → "Open Chat"
4. 记录日志中 "🔐 AUTHENTICATION CALL STARTED" 出现的次数

期望结果

  • "🔐 AUTHENTICATION CALL STARTED" 只出现 1 次
  • 浏览器弹窗次数:取决于 OAuth 流程1-2 次都是正常的)

测试 2: 缓存有效时

1. 首次登录成功(参考测试 1
2. 关闭 Chat UI WebView
3. 重新打开 Chat UI
4. 检查日志

期望结果

  • 看到 "Using cached authentication"
  • 不应该 出现 "🔐 AUTHENTICATION CALL STARTED"
  • 不需要重新登录

测试 3: 清除缓存后重新登录

1. 打开 Chat UI已登录状态
2. 执行: Cmd+Shift+P → "Clear Authentication Cache"
3. 检查日志是否有 "Resetting agent state"
4. 关闭 Chat UI
5. 重新打开 Chat UI
6. 检查是否需要重新登录

期望结果

  • 清除缓存后看到 "Resetting agent state"
  • 重新打开时需要登录
  • "🔐 AUTHENTICATION CALL STARTED" 只出现 1 次

测试 4: agentInitialized 标志

1. 打开 Chat UI首次
2. 不要关闭 WebView
3. 再次执行: Cmd+Shift+P → "Open Chat"
4. 检查日志

期望结果

  • 第二次打开时看到 "Agent already initialized, reusing existing connection"
  • 不应该 重新初始化

🎯 下一步行动

如果测试失败(仍然两次登录)

  1. 收集完整日志

    • 从 Extension Host 启动开始
    • 到第二次 "AUTHENTICATION CALL STARTED" 结束
    • 包括完整的调用栈信息
  2. 检查调用栈

    • 确认两次调用是从哪里触发的
    • 第一次:应该是 line 162 (needsAuth 分支)
    • 第二次:应该是 line 184 (缓存失效重试)
  3. 确认是否是"情况 1"

    • 如果确实是缓存失效导致的第二次认证
    • 需要调查为什么 session 创建会失败
  4. 可能的解决方案

    • 如果是缓存时间太长,可以缩短 AUTH_CACHE_DURATION
    • 如果是 session 创建逻辑有问题,需要修复 newSessionWithRetry
    • 如果是 CLI 的问题,需要向 Qwen Code 团队反馈

如果是 OAuth 流程本身的问题

  • 联系 Qwen Code 团队
  • 确认是否可以优化 OAuth 流程,减少用户交互次数
  • 或者在文档中说明这是正常行为

创建日期: 2025-11-17
最后更新: 2025-11-17
负责人: VSCode Extension Team