fix: sync OpenAI plan type from usage limit errors

This commit is contained in:
XiaoYu994
2026-05-11 16:22:40 +08:00
parent dbc8ae658c
commit c3a1471775
4 changed files with 122 additions and 8 deletions
@@ -824,6 +824,7 @@ func (s *RateLimitService) handleCustomErrorCode(ctx context.Context, account *A
func (s *RateLimitService) handle429(ctx context.Context, account *Account, headers http.Header, responseBody []byte) {
// 1. OpenAI 平台:优先尝试解析 x-codex-* 响应头(用于 rate_limit_exceeded
if account.Platform == PlatformOpenAI {
persistOpenAI429PlanType(ctx, s.accountRepo, account, responseBody)
s.persistOpenAICodexSnapshot(ctx, account, headers)
if resetAt := s.calculateOpenAI429ResetTime(headers); resetAt != nil {
if err := s.accountRepo.SetRateLimited(ctx, account.ID, *resetAt); err != nil {
@@ -1198,6 +1199,55 @@ func parseOpenAIRateLimitResetTime(body []byte) *int64 {
return nil
}
func parseOpenAIRateLimitPlanType(body []byte) string {
var parsed map[string]any
if err := json.Unmarshal(body, &parsed); err != nil {
return ""
}
errObj, ok := parsed["error"].(map[string]any)
if !ok {
return ""
}
errType, _ := errObj["type"].(string)
if errType != "usage_limit_reached" && errType != "rate_limit_exceeded" {
return ""
}
planType, _ := errObj["plan_type"].(string)
return strings.ToLower(strings.TrimSpace(planType))
}
func persistOpenAI429PlanType(ctx context.Context, repo AccountRepository, account *Account, body []byte) {
if repo == nil || account == nil || account.Platform != PlatformOpenAI {
return
}
planType := parseOpenAIRateLimitPlanType(body)
if planType == "" {
return
}
current := strings.TrimSpace(account.GetCredential("plan_type"))
if strings.EqualFold(current, planType) {
return
}
if _, err := repo.BulkUpdate(ctx, []int64{account.ID}, AccountBulkUpdate{
Credentials: map[string]any{"plan_type": planType},
}); err != nil {
slog.Warn("openai_429_plan_type_sync_failed", "account_id", account.ID, "plan_type", planType, "error", err)
return
}
if account.Credentials == nil {
account.Credentials = make(map[string]any, 1)
}
account.Credentials["plan_type"] = planType
slog.Info("openai_429_plan_type_synced", "account_id", account.ID, "previous_plan_type", current, "plan_type", planType)
}
// handle529 处理529过载错误
// 根据配置决定是否暂停账号调度及冷却时长
func (s *RateLimitService) handle529(ctx context.Context, account *Account) {