Commit a8ba36d3c24d930affaa383a5a3f541e8953a559

Authored by yibo
1 parent 103b8cdd

fix: 拦截格式错乱的纯文本 API Error 日志

修复 Claude CLI 遇到严重 API 错误 (如 Http 429) 时,输出的不是合法 JSON,而是像
'MiniMax 检查失败: HTTP 429: {...}' 这样的纯文本行。
旧版本在 JSON.parse 失败后直接忽略。
新版本增加 fallback,匹配非 JSON 行中的错误关键字并强制中断死等和前端展示。
packages/acp-core/protocol/ClaudeCliProtocol.js
@@ -96,7 +96,20 @@ class ClaudeCliProtocol extends EventEmitter { @@ -96,7 +96,20 @@ class ClaudeCliProtocol extends EventEmitter {
96 const event = JSON.parse(line); 96 const event = JSON.parse(line);
97 this._handleStreamEvent(event); 97 this._handleStreamEvent(event);
98 } catch (e) { 98 } catch (e) {
99 - // 非 JSON 行,忽略 99 + // 非 JSON 行:拦截纯文本的崩溃日志或 API 拒绝日志
  100 + const msg = line.trim();
  101 + if (msg) {
  102 + console.log(`[ClaudeCliProtocol] 📝 非JSON文本:`, msg.substring(0, 300));
  103 + // 触发类似 stderr 的检测逻辑
  104 + if (this._promptReject && /error|rate.?limit|429|401|403|authentication|api.?key|quota|billing|失败/i.test(msg)) {
  105 + const err = new Error(`API 请求失败 (Raw): ${msg.substring(0, 500)}`);
  106 + console.error(`[ClaudeCliProtocol] 拦截到底层纯文本错误:`, err.message);
  107 + if (this._idleTimer) { clearTimeout(this._idleTimer); this._idleTimer = null; }
  108 + this._promptReject(err);
  109 + this._promptResolve = null;
  110 + this._promptReject = null;
  111 + }
  112 + }
100 } 113 }
101 } 114 }
102 }); 115 });
server/routes/agent-chat.js
@@ -1753,7 +1753,7 @@ router.post('/:agentId/chat', async (req, res) => { @@ -1753,7 +1753,7 @@ router.post('/:agentId/chat', async (req, res) => {
1753 entry.protocol.on('disconnected', onDisconnected); 1753 entry.protocol.on('disconnected', onDisconnected);
1754 1754
1755 // 发出状态以便前端展示不卡壳 1755 // 发出状态以便前端展示不卡壳
1756 - sendSSE('agent_output', { agent: agentId, message: `_[系统正在通过 \`${fullSystemConfig.model}\` 请求响应...]_\\n\\n` }); 1756 + sendSSE('agent_output', { agent: agentId, message: `_[请求已发送,等待底层大模型响应...]_\\n\\n` });
1757 1757
1758 // 发送 prompt 并等待完成 1758 // 发送 prompt 并等待完成
1759 await entry.protocol.sendPrompt(prompt); 1759 await entry.protocol.sendPrompt(prompt);