fix(proxy): 首包前不可重试失败补齐 OpenAI 直连与入站 WS 两条路径#333
Conversation
#318/#332 只覆盖了 Responses/ChatCompletions 主流式路径,本次补齐: OpenAI Responses API 直连分支(IsOpenAIResponsesAPI): - 回调拦截首 token 前的 response.failed,收尾 flush 加 wroteAnyBody 守卫, 循环外覆盖 Content-Type 后按 outcome.logStatusCode 返回 JSON 错误, 与主路径行为一致(此前该分支把失败事件写进 200 流) 入站 WebSocket(responses_ws.go): - WS 升级后没有 HTTP 状态码可用,等价语义为:首 token 前不可重试的 response.failed 不透传原始失败帧,改写结构化 error 帧后按错误类别 用非正常 close code 关闭(429→1013,其余 4xx→1008,5xx→1011), 下游不再把失败会话当正常收尾 - 可重试失败不拦截:silent retry 开启时仍换号重试,关闭时按既有约定 原样透传失败帧(TestResponsesWebSocketSilentRetryDisabledRelaysRetryableFailure) 测试: - 新增 close code 映射单测 - 新增端到端 WS 测试:断言 error 帧 + 1008 close + 不换号重试
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThis change updates HTTP SSE and WebSocket streaming handlers for ChangesResponse.failed abort handling
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant Handler as HTTP Handler
participant WSHandler as WebSocket Handler
participant Upstream
Note over Client,Upstream: HTTP SSE stream, pre-first-token failure
Client->>Handler: POST /v1/responses (stream)
Handler->>Upstream: forward request
Upstream-->>Handler: response.failed (non-retryable)
Handler->>Handler: abortedForHTTPError=true, skip flush
Handler-->>Client: JSON upstream_error (logStatusCode)
Note over Client,Upstream: WebSocket stream, pre-first-token failure
Client->>WSHandler: open WebSocket
WSHandler->>Upstream: forward request
Upstream-->>WSHandler: response.failed (non-retryable)
WSHandler->>WSHandler: abortedForErrorClose=true, discard pending frames
WSHandler->>WSHandler: map status to close code
WSHandler-->>Client: structured error frame + WebSocket close
Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
说明
#332(含 #318)只覆盖了 Responses/ChatCompletions 主流式路径,本 PR 补齐剩余两条:
OpenAI Responses API 直连分支(
IsOpenAIResponsesAPI)与主路径同构的三处修改:回调拦截首 token 前的
response.failed、收尾 flush 加wroteAnyBody守卫(避免空 flush 提前提交 200 header)、循环外覆盖 Content-Type 后按outcome.logStatusCode返回 JSON 错误。此前该分支把失败事件原样写进 200 流。入站 WebSocket(responses_ws.go)
WS 升级完成后没有 HTTP 状态码可用,等价语义为:
response.failed(如context_length_exceeded)不透传原始失败帧,改写结构化{"type":"error"}帧后按错误类别用非正常 close code 关闭:429→1013(TryAgainLater),其余 4xx→1008(PolicyViolation),5xx→1011(InternalServerErr)。下游中转/计费方不再把失败会话当正常收尾。TestResponsesWebSocketSilentRetryDisabledRelaysRetryableFailure保护)。测试
responsesWSCloseCodeForStatus映射单测go build ./...、go test ./...全部通过Summary by CodeRabbit