From 610b934f700d76ff24b253acfa0ec795b7e5a594 Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sun, 18 Jan 2026 15:02:17 +0800 Subject: [PATCH] =?UTF-8?q?fix(claude):=20=E5=8C=BA=E5=88=86403=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=B1=BB=E5=9E=8B=E5=B9=B6=E9=87=87=E5=8F=96=E4=B8=8D?= =?UTF-8?q?=E5=90=8C=E5=A4=84=E7=90=86=E6=8E=AA=E6=96=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 当遇到403错误时,新增对"temporarily suspended"错误的特殊处理: 1. 如果是账户暂停错误,直接标记凭证为不健康状态 2. 其他403错误则保持原有刷新UUID逻辑 3. 在普通请求、流式请求和用量查询中统一处理逻辑 --- src/providers/claude/claude-kiro.js | 56 ++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/src/providers/claude/claude-kiro.js b/src/providers/claude/claude-kiro.js index bc14a69..252fcff 100644 --- a/src/providers/claude/claude-kiro.js +++ b/src/providers/claude/claude-kiro.js @@ -1355,14 +1355,23 @@ async saveCredentialsToFile(filePath, newData) { if (status === 403) { console.log('[Kiro] Received 403. Marking credential as need refresh...'); - // 1. 先刷新 UUID - const newUuid = this._refreshUuid(); - if (newUuid) { - console.log(`[Kiro] UUID refreshed: ${this.uuid} -> ${newUuid}`); - this.uuid = newUuid; + // 检查是否为 temporarily suspended 错误 + const isSuspended = errorMessage && errorMessage.toLowerCase().includes('temporarily is suspended'); + + if (isSuspended) { + // temporarily suspended 错误:直接标记为不健康,不刷新 UUID + console.log('[Kiro] Account temporarily suspended. Marking as unhealthy without UUID refresh...'); + this._markCredentialUnhealthy('403 Forbidden - Account temporarily suspended', error); + } else { + // 其他 403 错误:先刷新 UUID,然后标记需要刷新 + const newUuid = this._refreshUuid(); + if (newUuid) { + console.log(`[Kiro] UUID refreshed: ${this.uuid} -> ${newUuid}`); + this.uuid = newUuid; + } + this._markCredentialNeedRefresh('403 Forbidden', error); } - this._markCredentialNeedRefresh('403 Forbidden', error); // Mark error for credential switch without recording error count error.shouldSwitchCredential = true; error.skipErrorCount = true; @@ -1871,14 +1880,23 @@ async saveCredentialsToFile(filePath, newData) { if (status === 403) { console.log('[Kiro] Received 403 in stream. Marking credential as need refresh...'); - // 1. 先刷新 UUID - const newUuid = this._refreshUuid(); - if (newUuid) { - console.log(`[Kiro] UUID refreshed: ${this.uuid} -> ${newUuid}`); - this.uuid = newUuid; + // 检查是否为 temporarily suspended 错误 + const isSuspended = errorMessage && errorMessage.toLowerCase().includes('temporarily is suspended'); + + if (isSuspended) { + // temporarily suspended 错误:直接标记为不健康,不刷新 UUID + console.log('[Kiro] Account temporarily suspended in stream. Marking as unhealthy without UUID refresh...'); + this._markCredentialUnhealthy('403 Forbidden - Account temporarily suspended', error); + } else { + // 其他 403 错误:先刷新 UUID,然后标记需要刷新 + const newUuid = this._refreshUuid(); + if (newUuid) { + console.log(`[Kiro] UUID refreshed: ${this.uuid} -> ${newUuid}`); + this.uuid = newUuid; + } + this._markCredentialNeedRefresh('403 Forbidden', error); } - this._markCredentialNeedRefresh('403 Forbidden', error); // Mark error for credential switch without recording error count error.shouldSwitchCredential = true; error.skipErrorCount = true; @@ -2770,7 +2788,19 @@ async saveCredentialsToFile(filePath, newData) { if (status === 403) { console.log('[Kiro] Received 403 on getUsageLimits. Marking credential as unhealthy (no retry)...'); - this._markCredentialNeedRefresh('403 Forbidden on usage query', formattedError); + + // 检查是否为 temporarily suspended 错误 + const isSuspended = errorMessage && errorMessage.toLowerCase().includes('temporarily is suspended'); + + if (isSuspended) { + // temporarily suspended 错误:直接标记为不健康,不刷新 UUID + console.log('[Kiro] Account temporarily suspended on usage query. Marking as unhealthy without UUID refresh...'); + this._markCredentialUnhealthy('403 Forbidden - Account temporarily suspended on usage query', formattedError); + } else { + // 其他 403 错误:标记需要刷新 + this._markCredentialNeedRefresh('403 Forbidden on usage query', formattedError); + } + throw formattedError; }