{"record":{"id":"bfe027477ca4d42d","repo":"flipped-aurora/gin-vue-admin","slug":"http-d","errorCode":null,"errorMessage":"下载技能失败, HTTP状态码: %d","messagePattern":"下载技能失败, HTTP状态码: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_skills.go","lineNumber":415,"sourceCode":"\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"构建下载请求失败: %w\", err)\n\t}\n\n\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 == \"\" {","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_skills.go#L397-L433","documentation":"The marketplace responded with a non-200 status to the downloadSkill POST. The code requires HTTP 200 before reading the body; any other status (404, 403, 500, 429...) yields this error carrying the status code.","triggerScenarios":"Calling DownloadOnlineSkill with an ID/version that doesn't exist (404), being rate-limited (429), marketplace auth/ACL rejection (403), or a marketplace-side error (5xx).","commonSituations":"Outdated client using a retired plugin_id; wrong version string; marketplace deployed behind a CDN/WAF that blocks datacenter IPs; marketplace maintenance window.","solutions":["Log the returned status code and read the response body for the marketplace's error message","Verify the skill ID and version exist on the marketplace (check the plugin shop listing)","Retry with backoff for 5xx/429; treat 4xx as a user-input problem","Check whether a proxy/WAF in front of the marketplace is rejecting datacenter traffic"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"func isMarketplaceStatusErr(err error) (int, bool) {\n    m := regexp.MustCompile(`HTTP状态码: (\\d+)`).FindStringSubmatch(err.Error())\n    if len(m) < 2 { return 0, false }\n    code, _ := strconv.Atoi(m[1])\n    return code, true\n}","tryCatchPattern":"if err := DownloadOnlineSkill(ctx, req); err != nil {\n    if code, ok := isMarketplaceStatusErr(err); ok {\n        switch {\n        case code == 404: // invalid skill id/version — fix user input\n        case code == 429 || code >= 500: // retry with backoff\n        default: // surface marketplace message\n        }\n    }\n}","preventionTips":["Validate skill ID/version against the marketplace listing before download","Retry 5xx/429 with backoff; never retry 4xx input errors","Log the status code plus body for diagnostics","Watch marketplace status pages / announcements"],"tags":["go","http","http-status"],"backgroundTag":"unexpected-http-status","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}