fix(antigravity): 优化 token 刷新错误处理
- 不可重试错误(invalid_grant等)直接标记 error,不重试 - 其他错误仅记录日志,不标记 error(可能是临时网络问题) - 仅影响 Antigravity 账户,其他平台保持原有逻辑
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -171,6 +172,15 @@ func (s *TokenRefreshService) refreshWithRetry(ctx context.Context, account *Acc
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Antigravity 账户:不可重试错误直接标记 error 状态并返回
|
||||||
|
if account.Platform == PlatformAntigravity && isNonRetryableRefreshError(err) {
|
||||||
|
errorMsg := fmt.Sprintf("Token refresh failed (non-retryable): %v", err)
|
||||||
|
if setErr := s.accountRepo.SetError(ctx, account.ID, errorMsg); setErr != nil {
|
||||||
|
log.Printf("[TokenRefresh] Failed to set error status for account %d: %v", account.ID, setErr)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
lastErr = err
|
lastErr = err
|
||||||
log.Printf("[TokenRefresh] Account %d attempt %d/%d failed: %v",
|
log.Printf("[TokenRefresh] Account %d attempt %d/%d failed: %v",
|
||||||
account.ID, attempt, s.cfg.MaxRetries, err)
|
account.ID, attempt, s.cfg.MaxRetries, err)
|
||||||
@@ -183,11 +193,37 @@ func (s *TokenRefreshService) refreshWithRetry(ctx context.Context, account *Acc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 所有重试都失败,标记账号为error状态
|
// Antigravity 账户:其他错误仅记录日志,不标记 error(可能是临时网络问题)
|
||||||
errorMsg := fmt.Sprintf("Token refresh failed after %d retries: %v", s.cfg.MaxRetries, lastErr)
|
// 其他平台账户:重试失败后标记 error
|
||||||
if err := s.accountRepo.SetError(ctx, account.ID, errorMsg); err != nil {
|
if account.Platform == PlatformAntigravity {
|
||||||
log.Printf("[TokenRefresh] Failed to set error status for account %d: %v", account.ID, err)
|
log.Printf("[TokenRefresh] Account %d: refresh failed after %d retries: %v", account.ID, s.cfg.MaxRetries, lastErr)
|
||||||
|
} else {
|
||||||
|
errorMsg := fmt.Sprintf("Token refresh failed after %d retries: %v", s.cfg.MaxRetries, lastErr)
|
||||||
|
if err := s.accountRepo.SetError(ctx, account.ID, errorMsg); err != nil {
|
||||||
|
log.Printf("[TokenRefresh] Failed to set error status for account %d: %v", account.ID, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return lastErr
|
return lastErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isNonRetryableRefreshError 判断是否为不可重试的刷新错误
|
||||||
|
// 这些错误通常表示凭证已失效,需要用户重新授权
|
||||||
|
func isNonRetryableRefreshError(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
msg := strings.ToLower(err.Error())
|
||||||
|
nonRetryable := []string{
|
||||||
|
"invalid_grant", // refresh_token 已失效
|
||||||
|
"invalid_client", // 客户端配置错误
|
||||||
|
"unauthorized_client", // 客户端未授权
|
||||||
|
"access_denied", // 访问被拒绝
|
||||||
|
}
|
||||||
|
for _, needle := range nonRetryable {
|
||||||
|
if strings.Contains(msg, needle) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user