flipped-aurora/gin-vue-admin · error
读取上游流式响应失败: %w
Error message
读取上游流式响应失败: %w
What it means
In streaming mode the handler reads the upstream SSE body line-by-line with bufio.Reader.ReadString. If ReadString returns an error other than io.EOF mid-stream (connection reset, broken pipe, timeout), the read loop aborts with this wrapped error after logging how many blocks were already forwarded.
Source
Thrown at server/api/v1/system/sys_auto_code_sse.go:118
return errors.New("当前响应不支持流式输出")
}
prepareSSEHeaders(c)
c.Status(http.StatusOK)
flusher.Flush()
reader := bufio.NewReader(res.Body)
lines := make([]string, 0, 8)
blockCount := 0
logger.WithCtx(c.Request.Context()).Mod("biz").Info("LLMAutoSSE 开始读取上游流数据...")
for {
logger.WithCtx(c.Request.Context()).Mod("biz").Debug("LLMAutoSSE 等待读取下一行...")
line, readErr := reader.ReadString('\n')
if readErr != nil && !errors.Is(readErr, io.EOF) {
logger.WithCtx(c.Request.Context()).Mod("biz").Field("已转发块数", blockCount).Err(readErr).Error("LLMAutoSSE 读取上游流失败")
return fmt.Errorf("读取上游流式响应失败: %w", readErr)
}
line = strings.TrimRight(line, "\r\n")
if line == "" {
if len(lines) > 0 {
blockCount++
if blockCount <= 3 {
logger.WithCtx(c.Request.Context()).Mod("biz").Field("block", blockCount).Field("lines", lines).Debug("LLMAutoSSE 转发 SSE 块")
}
}
if err := emitSSEBlock(c, lines); err != nil {
return err
}
lines = lines[:0]
} else {
lines = append(lines, line)
}
View on GitHub (pinned to 3136500ef3)
Solutions
- Inspect the wrapped error for timeout vs connection-reset and fix accordingly (timeouts, keep-alive settings)
- Increase idle/read timeouts on any proxy between the service and the LLM upstream
- Implement resumable or retry logic at a higher level for long streams
- Check upstream provider status; 5xx/stream aborts during generation are provider-side
Defensive patterns
Strategy: retry
Try / catch
line, readErr := reader.ReadString('\n')
if readErr != nil && !errors.Is(readErr, io.EOF) {
if isRetryableNetErr(readErr) { /* reconnect & resume stream */ }
return readErr
} Prevention
- Configure LB/proxy idle timeouts above the max generation duration
- Send SSE keep-alive pings upstream-side to keep connections warm
- Surface partial results already forwarded before the drop
When it happens
Trigger: During active SSE streaming, the upstream connection drops: res.Body read fails with a network error (not a clean EOF), e.g. upstream crash, idle-timeout kill, or LB connection teardown.
Common situations: Long generations exceed an intermediate proxy's idle timeout; upstream restarts during a stream; client network flakes; keep-alive limits on LB.
Related errors
- LLM stream request timed out
- 上游大模型流式服务返回非 2xx: status=%d content-type=%s read-body-err=%w
- 向客户端写入流式响应失败: %w
- 上游大模型流式服务返回非 2xx: status=%d content-type=%s read-body-err=%w
- 调用上游大模型流式服务失败: %w
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/f8e3ac5a0a8b3789.
Report an issue: GitHub.