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

  1. Inspect the wrapped error for timeout vs connection-reset and fix accordingly (timeouts, keep-alive settings)
  2. Increase idle/read timeouts on any proxy between the service and the LLM upstream
  3. Implement resumable or retry logic at a higher level for long streams
  4. 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

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


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/f8e3ac5a0a8b3789. Report an issue: GitHub.