fix: restore non-failover error passthrough from 7b156489

This commit is contained in:
erio
2026-02-07 14:24:55 +08:00
parent 43a4840daf
commit edb0937024
8 changed files with 404 additions and 18 deletions

View File

@@ -2576,24 +2576,20 @@ func (s *GatewayService) selectAccountWithMixedScheduling(ctx context.Context, g
// 对于 Antigravity 平台,会先获取映射后的最终模型名(包括 thinking 后缀)再检查支持
func (s *GatewayService) isModelSupportedByAccountWithContext(ctx context.Context, account *Account, requestedModel string) bool {
if account.Platform == PlatformAntigravity {
// Antigravity 平台使用专门的模型支持检查
if strings.TrimSpace(requestedModel) == "" {
return true
}
if !IsAntigravityModelSupported(requestedModel) {
// 使用与转发阶段一致的映射逻辑:自定义映射优先 → 默认映射兜底
mapped := mapAntigravityModel(account, requestedModel)
if mapped == "" {
return false
}
// 先用默认映射获取基础模型名,再应用 thinking 后缀
defaultMapped, exists := domain.DefaultAntigravityModelMapping[requestedModel]
if !exists || defaultMapped == "" {
return false
}
finalModel := defaultMapped
// 应用 thinking 后缀后检查最终模型是否在账号映射中
if enabled, ok := ctx.Value(ctxkey.ThinkingEnabled).(bool); ok {
finalModel = applyThinkingModelSuffix(finalModel, enabled)
finalModel := applyThinkingModelSuffix(mapped, enabled)
return account.IsModelSupported(finalModel)
}
// 使用最终模型名检查 model_mapping 支持
return account.IsModelSupported(finalModel)
return true
}
return s.isModelSupportedByAccount(account, requestedModel)
}
@@ -2601,15 +2597,10 @@ func (s *GatewayService) isModelSupportedByAccountWithContext(ctx context.Contex
// isModelSupportedByAccount 根据账户平台检查模型支持(无 context用于非 Antigravity 平台)
func (s *GatewayService) isModelSupportedByAccount(account *Account, requestedModel string) bool {
if account.Platform == PlatformAntigravity {
// Antigravity 应使用 isModelSupportedByAccountWithContext
// 这里作为兼容保留,使用原始模型名检查
if strings.TrimSpace(requestedModel) == "" {
return true
}
if !IsAntigravityModelSupported(requestedModel) {
return false
}
return account.IsModelSupported(requestedModel)
return mapAntigravityModel(account, requestedModel) != ""
}
// OAuth/SetupToken 账号使用 Anthropic 标准映射短ID → 长ID
if account.Platform == PlatformAnthropic && account.Type != AccountTypeAPIKey {
@@ -3919,6 +3910,34 @@ func (s *GatewayService) handleErrorResponse(ctx context.Context, resp *http.Res
)
}
// 非 failover 错误也支持错误透传规则匹配。
if status, errType, errMsg, matched := applyErrorPassthroughRule(
c,
account.Platform,
resp.StatusCode,
body,
http.StatusBadGateway,
"upstream_error",
"Upstream request failed",
); matched {
c.JSON(status, gin.H{
"type": "error",
"error": gin.H{
"type": errType,
"message": errMsg,
},
})
summary := upstreamMsg
if summary == "" {
summary = errMsg
}
if summary == "" {
return nil, fmt.Errorf("upstream error: %d (passthrough rule matched)", resp.StatusCode)
}
return nil, fmt.Errorf("upstream error: %d (passthrough rule matched) message=%s", resp.StatusCode, summary)
}
// 根据状态码返回适当的自定义错误响应(不透传上游详细信息)
var errType, errMsg string
var statusCode int
@@ -4050,6 +4069,33 @@ func (s *GatewayService) handleRetryExhaustedError(ctx context.Context, resp *ht
)
}
if status, errType, errMsg, matched := applyErrorPassthroughRule(
c,
account.Platform,
resp.StatusCode,
respBody,
http.StatusBadGateway,
"upstream_error",
"Upstream request failed after retries",
); matched {
c.JSON(status, gin.H{
"type": "error",
"error": gin.H{
"type": errType,
"message": errMsg,
},
})
summary := upstreamMsg
if summary == "" {
summary = errMsg
}
if summary == "" {
return nil, fmt.Errorf("upstream error: %d (retries exhausted, passthrough rule matched)", resp.StatusCode)
}
return nil, fmt.Errorf("upstream error: %d (retries exhausted, passthrough rule matched) message=%s", resp.StatusCode, summary)
}
// 返回统一的重试耗尽错误响应
c.JSON(http.StatusBadGateway, gin.H{
"type": "error",