{"record":{"id":"12bda803d3dd7a25","repo":"flipped-aurora/gin-vue-admin","slug":"w-12bda8","errorCode":null,"errorMessage":"读取大模型响应失败: %w","messagePattern":"读取大模型响应失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/auto_code_llm.go","lineNumber":39,"sourceCode":"\t\treturn nil, err\n\t}\n\n\tres, err := request.HttpRequestWithContextAndTimeout(\n\t\tctx,\n\t\tpath,\n\t\thttp.MethodPost,\n\t\tnil,\n\t\tnil,\n\t\tllm,\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"调用上游大模型服务失败: %w\", err)\n\t}\n\tdefer res.Body.Close()\n\n\tbody, err := io.ReadAll(res.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"读取大模型响应失败: %w\", err)\n\t}\n\n\tbodyPreview := previewResponseBody(body)\n\tcontentType := res.Header.Get(\"Content-Type\")\n\tif res.StatusCode < 200 || res.StatusCode >= 300 {\n\t\treturn nil, fmt.Errorf(\"上游大模型服务返回非 2xx: status=%d content-type=%s body=%s\", res.StatusCode, contentType, bodyPreview)\n\t}\n\n\tvar resStruct commonResp.Response\n\tif err = json.Unmarshal(body, &resStruct); err != nil {\n\t\treturn nil, fmt.Errorf(\"解析大模型响应失败: status=%d content-type=%s body=%s err=%w\", res.StatusCode, contentType, bodyPreview, err)\n\t}\n\n\tif resStruct.Code != commonResp.SUCCESS {\n\t\treturn nil, fmt.Errorf(\"大模型服务返回业务错误: code=%d msg=%s body=%s\", resStruct.Code, resStruct.Msg, bodyPreview)\n\t}\n\n\treturn resStruct.Data, nil","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/auto_code_llm.go#L21-L57","documentation":"LLMAuto reads the full HTTP response body with io.ReadAll after the request succeeded; if that read fails (connection reset mid-response, context deadline while streaming, truncated chunked body), this message wraps the read error. It signals the response was received but could not be fully drained.","triggerScenarios":"io.ReadAll(res.Body) returns non-nil err after a 2xx-or-not HTTP response — typically the upstream closed the connection mid-body or the request context timed out while the body was being read.","commonSituations":"LLM gateway/proxy (nginx, cloud LB) with short idle timeouts killing slow responses, large responses over unstable networks, server-side crash mid-response, context deadline hit during a slow LLM generation.","solutions":["Increase the client/context timeout to accommodate slow LLM responses","Check intermediary proxies/LB idle-timeout settings and raise them above the LLM latency","Retry the request; transient mid-body resets are often one-off","Inspect the wrapped error to distinguish context deadline vs connection reset"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"var body []byte\nvar lastErr error\nfor attempt := 0; attempt < 3; attempt++ {\n    body, lastErr = attemptRead(ctx, llmCfg)\n    if lastErr == nil { break }\n    time.Sleep(time.Duration(1<<attempt) * time.Second)\n}\nif lastErr != nil { return lastErr }","preventionTips":["Raise client/context timeout above worst-case LLM latency","Raise proxy/LB idle timeouts for long-running LLM endpoints","Prefer stable networks for code-gen workloads; avoid reading huge bodies over flaky links","Wrap reads with a bounded retry for transient resets"],"tags":["network","http","io","llm"],"backgroundTag":"response-body-read-failed","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}