fix(openai-ws): classify canceled client streams

This commit is contained in:
Ray
2026-08-31 21:04:29 +08:00
parent 52374af940
commit a10ff1255c
4 changed files with 317 additions and 27 deletions
@@ -0,0 +1,25 @@
package handler
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/require"
)
func TestOpenAIEnsureForwardErrorResponse_SkipsCanceledClient(t *testing.T) {
gin.SetMode(gin.TestMode)
recorder := httptest.NewRecorder()
c, _ := gin.CreateTestContext(recorder)
ctx, cancel := context.WithCancel(context.Background())
c.Request = httptest.NewRequest(http.MethodPost, EndpointResponses, nil).WithContext(ctx)
cancel()
h := &OpenAIGatewayHandler{}
require.False(t, h.ensureForwardErrorResponse(c, true))
require.Equal(t, statusClientClosedRequest, c.Writer.Status())
require.Empty(t, recorder.Body.String())
}
@@ -792,6 +792,22 @@ func (h *OpenAIGatewayHandler) Responses(c *gin.Context) {
})
}
if err != nil {
if result != nil && result.ClientDisconnect {
reqLog.Info("openai.client_disconnected",
zap.Int64("account_id", account.ID),
zap.Error(err),
)
submitResponsesUsage(result)
return
}
if failoverClientGone(c) {
reqLog.Info("openai.client_disconnected",
zap.Int64("account_id", account.ID),
zap.Error(err),
)
submitResponsesUsage(result)
return
}
if result != nil && result.ImageCount > 0 {
reqLog.Warn("openai.forward_partial_error_with_image_result",
zap.Int64("account_id", account.ID),
@@ -3087,6 +3103,10 @@ func (h *OpenAIGatewayHandler) ensureForwardErrorResponse(c *gin.Context, stream
if c == nil || c.Writer == nil {
return false
}
if c.Request != nil && errors.Is(c.Request.Context().Err(), context.Canceled) {
failoverClientGone(c)
return false
}
// 先停 compact 心跳再读 Writer 状态,避免与心跳 goroutine 竞争。
compactKeepaliveCommitted := service.StopOpenAICompactSSEKeepaliveCommitted(c)
if compactKeepaliveCommitted {