diff --git a/backend/internal/service/openai_gateway_passthrough.go b/backend/internal/service/openai_gateway_passthrough.go index 80236b2334..bbf80c97c9 100644 --- a/backend/internal/service/openai_gateway_passthrough.go +++ b/backend/internal/service/openai_gateway_passthrough.go @@ -517,9 +517,6 @@ func validOpenAIPassthroughRetryAfter(raw string, now time.Time) bool { } func writeSanitizedOpenAIPassthroughError(c *gin.Context, upstreamStatus int, upstreamHeaders http.Header) { - if c == nil { - return - } downstreamStatus := upstreamStatus message := "Upstream request failed" switch upstreamStatus { @@ -534,6 +531,15 @@ func writeSanitizedOpenAIPassthroughError(c *gin.Context, upstreamStatus int, up message = "Upstream service temporarily unavailable" } } + writeOpenAIPassthroughErrorEnvelope(c, downstreamStatus, upstreamHeaders, message) +} + +// writeOpenAIPassthroughErrorEnvelope 以本地 JSON 信封 + 净化后的头策略写出 +// 错误响应;message 由调用方决定(净化通用文案或脱敏后的上游消息)。 +func writeOpenAIPassthroughErrorEnvelope(c *gin.Context, downstreamStatus int, upstreamHeaders http.Header, message string) { + if c == nil { + return + } body, _ := json.Marshal(gin.H{ "error": gin.H{ "type": "upstream_error", @@ -645,7 +651,14 @@ func (s *OpenAIGatewayService) handleErrorResponsePassthrough( Detail: upstreamDetail, UpstreamResponseBody: upstreamDetail, }) - writeSanitizedOpenAIPassthroughError(c, resp.StatusCode, resp.Header) + // context-window 超限是确定性请求失败(shouldFailoverOpenAIPassthroughResponse + // 已保证不切号),其文案对客户端可操作(如触发自动压缩);在净化信封内保留 + // 脱敏后的上游消息,而不是抹成通用文案。 + if isOpenAIContextWindowError(upstreamMsg, body) && upstreamMsg != "" { + writeOpenAIPassthroughErrorEnvelope(c, resp.StatusCode, resp.Header, upstreamMsg) + } else { + writeSanitizedOpenAIPassthroughError(c, resp.StatusCode, resp.Header) + } return fmt.Errorf("upstream error: %d (client response sanitized)", resp.StatusCode) } diff --git a/backend/internal/service/openai_oauth_passthrough_test.go b/backend/internal/service/openai_oauth_passthrough_test.go index 8b731d37a6..5fc5d2996a 100644 --- a/backend/internal/service/openai_oauth_passthrough_test.go +++ b/backend/internal/service/openai_oauth_passthrough_test.go @@ -1049,20 +1049,23 @@ func TestOpenAIGatewayService_APIKeyPassthrough_RebuildsUpstreamErrors(t *testin wantStatus: http.StatusBadGateway, wantMessage: "Upstream authentication failed", }, + // 瞬时 5xx(500/502/503/504/520-524)对 API-key 账号已改走多账号 + // failover(见 APIKeyPassthrough_Transient5xxTriggersFailover),此处 + // 改用非瞬时 5xx 状态码,继续覆盖净化重建路径。 { name: "html 5xx", - statusCode: http.StatusBadGateway, + statusCode: 530, contentType: "text/html; charset=UTF-8", - responseBody: `