{"record":{"id":"c07db2734fef3f09","repo":"fish2018/pansou","slug":"d-c07db2","errorCode":null,"errorMessage":"下载链接请求状态码: %d","messagePattern":"下载链接请求状态码: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/cyg/cyg.go","lineNumber":246,"sourceCode":"\t// 创建请求对象\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", downloadURL, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"创建下载链接请求失败: %w\", err)\n\t}\n\n\t// 设置请求头\n\tp.setRequestHeaders(req)\n\n\t// 发送请求\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"下载链接请求失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// 检查状态码\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"下载链接请求状态码: %d\", resp.StatusCode)\n\t}\n\n\t// 解析响应\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"读取下载链接响应失败: %w\", err)\n\t}\n\n\tvar downloadData []CygDownload\n\tif err := json.Unmarshal(body, &downloadData); err != nil {\n\t\treturn nil, fmt.Errorf(\"下载链接JSON解析失败: %w\", err)\n\t}\n\n\t// 转换为model.Link格式\n\treturn p.convertToLinks(downloadData), nil\n}\n\n// convertToSearchResult 转换为标准搜索结果格式","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/cyg/cyg.go#L228-L264","documentation":"getDownloadLinks returns this when the download-links API responds with an HTTP status other than 200. It is a deliberate guard: the plugin only knows how to parse a 200 JSON body, so any other status (403, 404, 5xx) is reported with the numeric code.","triggerScenarios":"The GET for download links completes but resp.StatusCode != 200 — e.g. the video/episode id does not exist (404), the site rate-limits or blocks the client (403/429), or the server errors (500/502).","commonSituations":"Invalid or stale content ID passed by the caller, site added WAF/anti-bot protection returning 403, CDN 5xx during traffic spikes, or the API path changed after a site update.","solutions":["Log the actual status code and confirm the content id being requested is valid.","Retry later if the code is 5xx or 429 (rate limit); add backoff to doRequestWithRetry.","Inspect the response body for 403 to detect anti-bot/Cloudflare pages and add matching headers/cookies in setRequestHeaders.","Check if the site changed its API endpoint and update the URL in getDownloadLinks."],"exampleFix":"// before\nif resp.StatusCode != 200 {\n    return nil, fmt.Errorf(\"下载链接请求状态码: %d\", resp.StatusCode)\n}\n// after\nif resp.StatusCode != http.StatusOK {\n    body, _ := io.ReadAll(io.LimitReader(resp.Body, 512))\n    return nil, fmt.Errorf(\"下载链接请求状态码: %d, body: %s\", resp.StatusCode, body)\n}","handlingStrategy":"validation","validationCode":"if id == \"\" {\n    return errors.New(\"content id is required before fetching download links\")\n}","typeGuard":null,"tryCatchPattern":"links, err := p.getDownloadLinks(id)\nif err != nil {\n    if strings.Contains(err.Error(), \"状态码: 4\") {\n        // treat as client error: invalid id or blocked; don't retry blindly\n    }\n    return err\n}","preventionTips":["Validate content IDs before requesting download links.","Check plugin/site health when 403 or 429 codes appear repeatedly.","Log non-200 bodies to detect anti-bot pages early."],"tags":["http","status-code","go","api"],"backgroundTag":"http-non-200-response","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}