From 20f3f2049b3ed76c413cde39e2a6ef96f766b621 Mon Sep 17 00:00:00 2001 From: erio Date: Tue, 9 Jun 2026 16:50:37 +0800 Subject: [PATCH] fix(gateway): complete MarkResponseCommitted coverage for all platforms Add MarkResponseCommitted to 7 error-writing helper functions and 4 early-return branches in OpenAI handlers, plus 3 inline c.Data paths. Helper functions (1 line each, covers 60+ call sites): - writeGatewayCCError, writeResponsesError (Anthropic compat) - writeClaudeError, writeGoogleError (Gemini + Antigravity) - writeChatCompletionsError (Gemini Chat Completions compat) OpenAI handleErrorResponse/handleCompatErrorResponse: - passthrough rule and ShouldHandleErrorCode branches return before the existing MarkResponseCommitted, now each has its own Mark. Inline c.Data: Gemini ForwardNative (2) + Antigravity ForwardGemini (1). --- backend/internal/service/antigravity_gateway_service.go | 3 +++ .../internal/service/gateway_forward_as_chat_completions.go | 1 + backend/internal/service/gateway_forward_as_responses.go | 1 + backend/internal/service/gemini_messages_compat_service.go | 4 ++++ backend/internal/service/openai_gateway_chat_completions.go | 1 + backend/internal/service/openai_gateway_service.go | 4 ++++ 6 files changed, 14 insertions(+) diff --git a/backend/internal/service/antigravity_gateway_service.go b/backend/internal/service/antigravity_gateway_service.go index b93eb9685a..7bdda2e507 100644 --- a/backend/internal/service/antigravity_gateway_service.go +++ b/backend/internal/service/antigravity_gateway_service.go @@ -2447,6 +2447,7 @@ func (s *AntigravityGatewayService) ForwardGemini(ctx context.Context, c *gin.Co Detail: upstreamDetail, }) logger.LegacyPrintf("service.antigravity_gateway", "[antigravity-Forward] upstream error status=%d body=%s", resp.StatusCode, truncateForLog(unwrappedForOps, 500)) + MarkResponseCommitted(c) c.Data(resp.StatusCode, contentType, unwrappedForOps) return nil, fmt.Errorf("antigravity upstream error: %d", resp.StatusCode) } @@ -3644,6 +3645,7 @@ func mergeTextPartsToResponse(response map[string]any, textParts []string) map[s } func (s *AntigravityGatewayService) writeClaudeError(c *gin.Context, status int, errType, message string) error { + MarkResponseCommitted(c) c.JSON(status, gin.H{ "type": "error", "error": gin.H{"type": errType, "message": message}, @@ -3735,6 +3737,7 @@ func (s *AntigravityGatewayService) writeMappedClaudeError(c *gin.Context, accou } func (s *AntigravityGatewayService) writeGoogleError(c *gin.Context, status int, message string) error { + MarkResponseCommitted(c) statusStr := "UNKNOWN" switch status { case 400: diff --git a/backend/internal/service/gateway_forward_as_chat_completions.go b/backend/internal/service/gateway_forward_as_chat_completions.go index 16c10a3298..67324d63ba 100644 --- a/backend/internal/service/gateway_forward_as_chat_completions.go +++ b/backend/internal/service/gateway_forward_as_chat_completions.go @@ -498,6 +498,7 @@ func (s *GatewayService) handleCCStreamingFromAnthropic( // writeGatewayCCError writes an error in OpenAI Chat Completions format for // the Anthropic-upstream CC forwarding path. func writeGatewayCCError(c *gin.Context, statusCode int, errType, message string) { + MarkResponseCommitted(c) c.JSON(statusCode, gin.H{ "error": gin.H{ "type": errType, diff --git a/backend/internal/service/gateway_forward_as_responses.go b/backend/internal/service/gateway_forward_as_responses.go index f883ae870f..83adce6cad 100644 --- a/backend/internal/service/gateway_forward_as_responses.go +++ b/backend/internal/service/gateway_forward_as_responses.go @@ -520,6 +520,7 @@ func appendRawJSON(existing json.RawMessage, fragment string) json.RawMessage { // writeResponsesError writes an error response in OpenAI Responses API format. func writeResponsesError(c *gin.Context, statusCode int, code, message string) { + MarkResponseCommitted(c) c.JSON(statusCode, gin.H{ "error": gin.H{ "code": code, diff --git a/backend/internal/service/gemini_messages_compat_service.go b/backend/internal/service/gemini_messages_compat_service.go index 0d88140e24..375fb05326 100644 --- a/backend/internal/service/gemini_messages_compat_service.go +++ b/backend/internal/service/gemini_messages_compat_service.go @@ -1449,6 +1449,7 @@ func (s *GeminiMessagesCompatService) ForwardNative(ctx context.Context, c *gin. if contentType == "" { contentType = "application/json" } + MarkResponseCommitted(c) c.Data(http.StatusInternalServerError, contentType, respBody) return nil, fmt.Errorf("gemini upstream error: %d (skipped by error policy)", resp.StatusCode) case ErrorPolicyMatched, ErrorPolicyTempUnscheduled: @@ -1561,6 +1562,7 @@ func (s *GeminiMessagesCompatService) ForwardNative(ctx context.Context, c *gin. if contentType == "" { contentType = "application/json" } + MarkResponseCommitted(c) c.Data(resp.StatusCode, contentType, respBody) if upstreamMsg == "" { return nil, fmt.Errorf("gemini upstream error: %d", resp.StatusCode) @@ -2244,6 +2246,7 @@ func randomHex(nBytes int) string { } func (s *GeminiMessagesCompatService) writeClaudeError(c *gin.Context, status int, errType, message string) error { + MarkResponseCommitted(c) c.JSON(status, gin.H{ "type": "error", "error": gin.H{"type": errType, "message": message}, @@ -2252,6 +2255,7 @@ func (s *GeminiMessagesCompatService) writeClaudeError(c *gin.Context, status in } func (s *GeminiMessagesCompatService) writeGoogleError(c *gin.Context, status int, message string) error { + MarkResponseCommitted(c) c.JSON(status, gin.H{ "error": gin.H{ "code": status, diff --git a/backend/internal/service/openai_gateway_chat_completions.go b/backend/internal/service/openai_gateway_chat_completions.go index e6d438baea..8b75097349 100644 --- a/backend/internal/service/openai_gateway_chat_completions.go +++ b/backend/internal/service/openai_gateway_chat_completions.go @@ -853,6 +853,7 @@ func (s *OpenAIGatewayService) handleChatStreamingResponse( // writeChatCompletionsError writes an error response in OpenAI Chat Completions format. func writeChatCompletionsError(c *gin.Context, statusCode int, errType, message string) { + MarkResponseCommitted(c) c.JSON(statusCode, gin.H{ "error": gin.H{ "type": errType, diff --git a/backend/internal/service/openai_gateway_service.go b/backend/internal/service/openai_gateway_service.go index 0f19d043fa..6374ee91bd 100644 --- a/backend/internal/service/openai_gateway_service.go +++ b/backend/internal/service/openai_gateway_service.go @@ -4290,6 +4290,7 @@ func (s *OpenAIGatewayService) handleErrorResponse( "upstream_error", "Upstream request failed", ); matched { + MarkResponseCommitted(c) c.JSON(status, gin.H{ "error": gin.H{ "type": errType, @@ -4317,6 +4318,7 @@ func (s *OpenAIGatewayService) handleErrorResponse( Message: upstreamMsg, Detail: upstreamDetail, }) + MarkResponseCommitted(c) c.JSON(http.StatusInternalServerError, gin.H{ "error": gin.H{ "type": "upstream_error", @@ -4441,6 +4443,7 @@ func (s *OpenAIGatewayService) handleCompatErrorResponse( c, account.Platform, resp.StatusCode, body, http.StatusBadGateway, "api_error", "Upstream request failed", ); matched { + MarkResponseCommitted(c) writeError(c, status, errType, errMsg) if upstreamMsg == "" { upstreamMsg = errMsg @@ -4464,6 +4467,7 @@ func (s *OpenAIGatewayService) handleCompatErrorResponse( Message: upstreamMsg, Detail: upstreamDetail, }) + MarkResponseCommitted(c) writeError(c, http.StatusInternalServerError, "api_error", "Upstream gateway error") if upstreamMsg == "" { return nil, fmt.Errorf("upstream error: %d (not in custom error codes)", resp.StatusCode)