mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-23 17:00:49 +00:00
fix(antigravity): change VALIDATION_REQUIRED 403 to SetError and enrich degraded usage with account error status
- VALIDATION_REQUIRED now marks account as error (permanent) instead of temp unschedulable (10min) - When usage fetch fails with 401 but account has 403 error, show correct forbidden/banned status instead of needs_reauth
This commit is contained in:
@@ -700,6 +700,7 @@ func (s *AccountUsageService) getAntigravityUsage(ctx context.Context, account *
|
||||
fetchResult, err := s.antigravityQuotaFetcher.FetchQuota(fetchCtx, account, proxyURL)
|
||||
if err != nil {
|
||||
degraded := buildAntigravityDegradedUsage(err)
|
||||
enrichDegradedWithAccountError(degraded, account)
|
||||
s.cache.antigravityCache.Store(account.ID, &antigravityUsageCache{
|
||||
usageInfo: degraded,
|
||||
timestamp: time.Now(),
|
||||
@@ -785,6 +786,30 @@ func buildAntigravityDegradedUsage(err error) *UsageInfo {
|
||||
return info
|
||||
}
|
||||
|
||||
// enrichDegradedWithAccountError 结合账号错误状态修正降级 UsageInfo
|
||||
// 场景:被封号的账号 OAuth token 失效,FetchAvailableModels 返回 401,
|
||||
// 降级逻辑设置了 needs_reauth,但账号实际是 403 封号/需验证。
|
||||
// 此函数用账号的 error_message 覆盖降级信息,显示正确的 forbidden 状态。
|
||||
func enrichDegradedWithAccountError(info *UsageInfo, account *Account) {
|
||||
if info == nil || account == nil || account.Status != StatusError {
|
||||
return
|
||||
}
|
||||
msg := strings.ToLower(account.ErrorMessage)
|
||||
if !strings.Contains(msg, "403") && !strings.Contains(msg, "forbidden") &&
|
||||
!strings.Contains(msg, "violation") && !strings.Contains(msg, "validation") {
|
||||
return
|
||||
}
|
||||
fbType := classifyForbiddenType(account.ErrorMessage)
|
||||
info.IsForbidden = true
|
||||
info.ForbiddenType = fbType
|
||||
info.ForbiddenReason = account.ErrorMessage
|
||||
info.NeedsVerify = fbType == forbiddenTypeValidation
|
||||
info.IsBanned = fbType == forbiddenTypeViolation
|
||||
info.ValidationURL = extractValidationURL(account.ErrorMessage)
|
||||
info.ErrorCode = errorCodeForbidden
|
||||
info.NeedsReauth = false
|
||||
}
|
||||
|
||||
// addWindowStats 为 usage 数据添加窗口期统计
|
||||
// 使用独立缓存(1 分钟),与 API 缓存分离
|
||||
func (s *AccountUsageService) addWindowStats(ctx context.Context, account *Account, usage *UsageInfo) {
|
||||
|
||||
@@ -616,12 +616,8 @@ func (s *RateLimitService) handleAuthError(ctx context.Context, account *Account
|
||||
slog.Warn("account_disabled_auth_error", "account_id", account.ID, "error", errorMsg)
|
||||
}
|
||||
|
||||
// antigravityValidationBlockDuration Antigravity validation 类型 403 的临时封禁时长
|
||||
// 与 Antigravity-Manager 一致(10 分钟)
|
||||
const antigravityValidationBlockDuration = 10 * time.Minute
|
||||
|
||||
// handle403 处理 403 Forbidden 错误
|
||||
// Antigravity 平台区分 validation(临时不可调度)和 violation(永久 SetError);
|
||||
// Antigravity 平台区分 validation/violation/generic 三种类型,均 SetError 永久禁用;
|
||||
// 其他平台保持原有 SetError 行为。
|
||||
func (s *RateLimitService) handle403(ctx context.Context, account *Account, upstreamMsg string, responseBody []byte) (shouldDisable bool) {
|
||||
if account.Platform == PlatformAntigravity {
|
||||
@@ -637,7 +633,7 @@ func (s *RateLimitService) handle403(ctx context.Context, account *Account, upst
|
||||
}
|
||||
|
||||
// handleAntigravity403 处理 Antigravity 平台的 403 错误
|
||||
// validation(需要验证)→ 临时不可调度(到期自动恢复)
|
||||
// validation(需要验证)→ 永久 SetError(需人工去 Google 验证后恢复)
|
||||
// violation(违规封号)→ 永久 SetError(需人工处理)
|
||||
// generic(通用禁止)→ 永久 SetError
|
||||
func (s *RateLimitService) handleAntigravity403(ctx context.Context, account *Account, upstreamMsg string, responseBody []byte) (shouldDisable bool) {
|
||||
@@ -645,21 +641,12 @@ func (s *RateLimitService) handleAntigravity403(ctx context.Context, account *Ac
|
||||
|
||||
switch fbType {
|
||||
case forbiddenTypeValidation:
|
||||
// VALIDATION_REQUIRED: 临时不可调度,到期自动恢复
|
||||
until := time.Now().Add(antigravityValidationBlockDuration)
|
||||
reason := "Validation required (403)"
|
||||
// VALIDATION_REQUIRED: 永久禁用,需人工去 Google 验证后手动恢复
|
||||
msg := "Validation required (403): account needs Google verification"
|
||||
if upstreamMsg != "" {
|
||||
reason = "Validation required (403): " + upstreamMsg
|
||||
}
|
||||
if err := s.accountRepo.SetTempUnschedulable(ctx, account.ID, until, reason); err != nil {
|
||||
slog.Warn("antigravity_validation_block_failed", "account_id", account.ID, "error", err)
|
||||
} else {
|
||||
slog.Info("antigravity_validation_block_set",
|
||||
"account_id", account.ID,
|
||||
"until", until,
|
||||
"forbidden_type", fbType,
|
||||
)
|
||||
msg = "Validation required (403): " + upstreamMsg
|
||||
}
|
||||
s.handleAuthError(ctx, account, msg)
|
||||
return true
|
||||
|
||||
case forbiddenTypeViolation:
|
||||
|
||||
Reference in New Issue
Block a user