Commit ab16b18fdabcf4c5b0ce32a7d2c96eb84ea2ff56
1 parent
a8ba36d3
fix: 拦截 Claude CLI 最终的错误 报文
核心发现:当底层 API (如 MiniMax) 发生 429 时,Claude CLI 内部会自动开启一段漫长的 exponential backoff 重试逻辑(期间完全静默,耗时可达 3 分钟之久)。 如果最终依然失败,它会抛出一个合法的 JSON 格式的 `type: "result"` 报文,此时 `is_error: true`。 旧版本会将这个 result 报文当做正常的 Agent 文本流式处理,导致把错误输出混进正常消息里。 新版本增加逻辑,在解析到 result 且 is_error 为 true 时,不进行正常 resolve,而是立即 reject Promise 抛给上层,中断一切任务并给前台报红。
Showing
1 changed file
with
16 additions
and
0 deletions
packages/acp-core/protocol/ClaudeCliProtocol.js
| ... | ... | @@ -298,6 +298,22 @@ class ClaudeCliProtocol extends EventEmitter { |
| 298 | 298 | |
| 299 | 299 | case 'result': |
| 300 | 300 | this.sessionId = event.session_id || this.sessionId; |
| 301 | + | |
| 302 | + // 【核心发现】Claude CLI 会在自己内部重试(长达3分钟),最后如果依然失败, | |
| 303 | + // 会输出 result 事件,但带有 "is_error": true,并且 result 字段放着错误信息。 | |
| 304 | + if (event.is_error) { | |
| 305 | + if (this._idleTimer) { clearTimeout(this._idleTimer); this._idleTimer = null; } | |
| 306 | + const err = new Error(`API 请求失败 (内部重试后放弃): ${event.result || 'Unknown HTTP/RateLimit Error'}`); | |
| 307 | + console.error(`[ClaudeCliProtocol] 收到错误 result:`, err.message); | |
| 308 | + if (this._promptReject) { | |
| 309 | + this._promptReject(err); | |
| 310 | + this._promptResolve = null; | |
| 311 | + this._promptReject = null; | |
| 312 | + } | |
| 313 | + // 不要再发送正常 result notification | |
| 314 | + break; | |
| 315 | + } | |
| 316 | + | |
| 301 | 317 | this.emit('acp_event', { |
| 302 | 318 | type: 'notification', |
| 303 | 319 | method: 'session/result', | ... | ... |