{"record":{"id":"2f6e63931f570135","repo":"flipped-aurora/gin-vue-admin","slug":"w-2f6e63","errorCode":null,"errorMessage":"调用上游大模型服务失败: %w","messagePattern":"调用上游大模型服务失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/auto_code_llm.go","lineNumber":33,"sourceCode":"\t\"github.com/goccy/go-json\"\n)\n\nfunc (s *AutoCodeService) LLMAuto(ctx context.Context, llm common.JSONMap) (interface{}, error) {\n\tpath, err := buildLLMAutoPath(llm)\n\tif err != nil {\n\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}","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/auto_code_llm.go#L15-L51","documentation":"LLMAuto wraps any transport-layer failure from the HTTP call to the upstream LLM service in this generic message, preserving the underlying error via %w. It means the POST issued by request.HttpRequestWithContextAndTimeout (server/service/system/auto_code_llm.go:24-33) never completed — connection, DNS, TLS, timeout, or context cancellation. The library throws it because the request phase failed before any HTTP response could be inspected.","triggerScenarios":"Calling AutoCodeService.LLMAuto when the upstream endpoint is unreachable, the URL/path built by buildLLMAutoPath is wrong, DNS fails, TLS handshake fails, the context is cancelled, or the request timeout expires.","commonSituations":"LLM base URL misconfigured (wrong host/port, missing scheme), upstream provider down or behind a firewall/proxy, API host blocked in an offline/air-gapped environment, invalid self-signed certs, or the caller's ctx cancelled mid-request.","solutions":["Verify the LLM base URL/path in the llm config map (and buildLLMAutoPath) points to a reachable, scheme-correct endpoint","Test connectivity from the server host: curl the upstream URL to rule out DNS/firewall/proxy issues","Increase the request timeout or check that ctx is not being cancelled early by the caller","Unwrap the wrapped error (%w) with errors.Unwrap/log the original to see the exact transport cause"],"exampleFix":"// before: no reachability check, hard failure\nres, err := request.HttpRequestWithContextAndTimeout(ctx, path, http.MethodPost, nil, nil, llm)\nif err != nil { return nil, fmt.Errorf(\"调用上游大模型服务失败: %w\", err) }\n// after: pre-validate config and add bounded retry\nif base, ok := llm[\"base_url\"].(string); !ok || !strings.HasPrefix(base, \"http\") {\n    return nil, fmt.Errorf(\"LLM base_url 配置无效: %v\", llm[\"base_url\"])\n}\nres, err := request.HttpRequestWithContextAndTimeout(ctx, path, http.MethodPost, nil, nil, llm)\nif err != nil {\n    if errors.Is(err, context.DeadlineExceeded) { /* retry once or surface timeout hint */ }\n    return nil, fmt.Errorf(\"调用上游大模型服务失败: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"u, err := url.Parse(baseURL)\nif err != nil || (u.Scheme != \"http\" && u.Scheme != \"https\") || u.Host == \"\" {\n    return fmt.Errorf(\"无效的 LLM 地址: %q\", baseURL)\n}\nif conn, err := net.DialTimeout(\"tcp\", net.JoinHostPort(u.Hostname(), portOrDefault(u, \"443\")), 3*time.Second); err == nil {\n    conn.Close()\n}","typeGuard":null,"tryCatchPattern":"data, err := svc.LLMAuto(ctx, llmCfg)\nif err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        // retry with backoff or return timeout-specific message\n    }\n    return fmt.Errorf(\"LLM 调用不可达: %w\", err)\n}","preventionTips":["Validate the LLM base URL scheme/host at config load time, not call time","Set request timeouts well above expected LLM latency","Do not cancel the passed context before the LLM call completes","Health-check the upstream endpoint before long-running code-gen jobs"],"tags":["network","http","llm","go"],"backgroundTag":"upstream-request-failed","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}