fix: return degraded UsageInfo instead of 500 for Antigravity usage errors

When the Antigravity quota API returns non-403 errors (e.g. 401
UNAUTHENTICATED), return a UsageInfo with an error field instead of
propagating the error as HTTP 500. This matches Antigravity Manager's
behavior of gracefully displaying errors.
This commit is contained in:
erio
2026-03-10 05:44:31 +08:00
parent 4345862adf
commit 9a4137add3
3 changed files with 23 additions and 1 deletions
@@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"log"
"log/slog"
"math/rand/v2"
"net/http"
"strings"
@@ -191,6 +192,9 @@ type UsageInfo struct {
ForbiddenReason string `json:"forbidden_reason,omitempty"`
ForbiddenType string `json:"forbidden_type,omitempty"` // "validation" / "violation" / "forbidden"
ValidationURL string `json:"validation_url,omitempty"` // 验证/申诉链接
// 获取 usage 时的错误信息(降级返回,而非 500)
Error string `json:"error,omitempty"`
}
// ClaudeUsageResponse Anthropic API返回的usage结构
@@ -666,7 +670,20 @@ func (s *AccountUsageService) getAntigravityUsage(ctx context.Context, account *
// 3. 调用 API 获取额度
result, err := s.antigravityQuotaFetcher.FetchQuota(ctx, account, proxyURL)
if err != nil {
return nil, fmt.Errorf("fetch antigravity quota failed: %w", err)
// 降级返回带 error 字段的 UsageInfo,而非 500
now := time.Now()
errMsg := fmt.Sprintf("usage API error: %v", err)
slog.Warn("antigravity usage fetch failed, returning degraded response",
"account_id", account.ID, "error", err)
degraded := &UsageInfo{
UpdatedAt: &now,
Error: errMsg,
}
s.cache.antigravityCache.Store(account.ID, &antigravityUsageCache{
usageInfo: degraded,
timestamp: time.Now(),
})
return degraded, nil
}
// 4. 缓存结果
@@ -36,6 +36,10 @@
<!-- Usage data -->
<div v-else-if="usageInfo" class="space-y-1">
<!-- API error (degraded response) -->
<div v-if="usageInfo.error" class="text-xs text-amber-600 dark:text-amber-400 truncate max-w-[200px]" :title="usageInfo.error">
{{ usageInfo.error }}
</div>
<!-- 5h Window -->
<UsageProgressBar
v-if="usageInfo.five_hour"
+1
View File
@@ -784,6 +784,7 @@ export interface AccountUsageInfo {
forbidden_reason?: string
forbidden_type?: string // "validation" | "violation" | "forbidden"
validation_url?: string // 验证/申诉链接
error?: string // usage 获取失败时的错误信息
}
// OpenAI Codex usage snapshot (from response headers)