{"record":{"id":"6d8627351d43f0fc","repo":"flipped-aurora/gin-vue-admin","slug":"w-6d8627","errorCode":null,"errorMessage":"读取下载结果失败: %w","messagePattern":"读取下载结果失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_skills.go","lineNumber":420,"sourceCode":"\tdownloadReq, err := http.NewRequest(http.MethodPost, \"https://plugin.gin-vue-admin.com/api/shopPlugin/downloadSkill\", bytes.NewReader(body))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"构建下载请求失败: %w\", err)\n\t}\n\tdownloadReq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tdownloadResp, err := http.DefaultClient.Do(downloadReq)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"下载技能失败: %w\", err)\n\t}\n\tdefer downloadResp.Body.Close()\n\n\tif downloadResp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"下载技能失败, HTTP状态码: %d\", downloadResp.StatusCode)\n\t}\n\n\tmetaBody, err := io.ReadAll(downloadResp.Body)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"读取下载结果失败: %w\", err)\n\t}\n\n\tvar meta struct {\n\t\tData struct {\n\t\t\tURL string `json:\"url\"`\n\t\t} `json:\"data\"`\n\t}\n\tif err = json.Unmarshal(metaBody, &meta); err != nil {\n\t\treturn fmt.Errorf(\"解析下载结果失败: %w\", err)\n\t}\n\n\trealDownloadURL := strings.TrimSpace(meta.Data.URL)\n\tif realDownloadURL == \"\" {\n\t\treturn errors.New(\"下载结果缺少 url\")\n\t}\n\n\tzipResp, err := http.Get(realDownloadURL)\n\tif err != nil {","sourceCodeStart":402,"sourceCodeEnd":438,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_skills.go#L402-L438","documentation":"Reading the marketplace response body with io.ReadAll failed. The connection was established and returned 200, but the body could not be fully read — typically a dropped/reset connection mid-transfer or a read timeout.","triggerScenarios":"Calling DownloadOnlineSkill when the marketplace (or an intermediary proxy/LB) closes the TCP connection before the full JSON body arrives, or the body is truncated by a network interruption.","commonSituations":"Flaky network between server and marketplace; aggressive proxy idle timeouts; very large responses interrupted by LB body limits.","solutions":["Simply retry the download — this is usually transient","Check for proxy/LB timeouts between the server and the marketplace","Stabilize the network path (keepalive settings, MTU issues on VPN tunnels)","Inspect the wrapped error: 'unexpected EOF' or 'connection reset by peer' indicates mid-body disconnect"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := DownloadOnlineSkill(ctx, req); err != nil && strings.Contains(err.Error(), \"读取下载结果失败\") {\n    // body read interrupted; retry the download, it is transient\n}","preventionTips":["Use an HTTP client with sane timeouts and keepalives","Retry idempotent GET/POST downloads on read errors","Investigate proxies/LBs with aggressive idle timeouts","Prefer stable network paths for marketplace traffic"],"tags":["go","network","io"],"backgroundTag":"response-body-read-failed","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}