{"record":{"id":"553501b2548ee575","repo":"fish2018/pansou","slug":"w-553501","errorCode":null,"errorMessage":"创建下载链接请求失败: %w","messagePattern":"创建下载链接请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/cyg/cyg.go","lineNumber":231,"sourceCode":"\t\tresults = append(results, result)\n\t}\n\n\treturn results\n}\n\n// getDownloadLinks 获取指定帖子的下载链接\nfunc (p *CygPlugin) getDownloadLinks(client *http.Client, postID int) ([]model.Link, error) {\n\t// 构建下载链接获取URL\n\tdownloadURL := fmt.Sprintf(cygBaseURL+\"/wp-json/acg-studio/v1/download?id=%d\", postID)\n\n\t// 创建带超时的上下文\n\tctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n\tdefer cancel()\n\n\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// 解析响应","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/cyg/cyg.go#L213-L249","documentation":"In getDownloadLinks, http.NewRequestWithContext failed to construct the GET request for the post's download URL. This is a pre-network failure meaning the downloadURL string is malformed — usually derived from a post field (link/guid) that is empty or not a valid URL.","triggerScenarios":"Called (via an anonymous goroutine/callback that fetches download links for a search result) with a downloadURL built from a CygPost field that http.NewRequestWithContext cannot parse — empty link, relative URL, or URL with invalid characters.","commonSituations":"A post in the search results has an empty or relative link field; upstream changed the field containing the download path; the URL was constructed by string concatenation without url.Parse validation.","solutions":["Validate the downloadURL with url.Parse (scheme and host required) before creating the request and skip posts with invalid links.","Log the offending URL in the error to identify which post produced it.","Ensure the field used to build downloadURL is non-empty and absolute; fall back to another field (e.g. post.link) if empty.","Escape or sanitize any user/post-derived path segments before concatenation."],"exampleFix":"// before\nreq, err := http.NewRequestWithContext(ctx, \"GET\", downloadURL, nil)\nif err != nil {\n    return nil, fmt.Errorf(\"创建下载链接请求失败: %w\", err)\n}\n// after\nu, perr := url.Parse(downloadURL)\nif perr != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return nil, fmt.Errorf(\"无效的下载链接: %q (%v)\", downloadURL, perr)\n}\nreq, err := http.NewRequestWithContext(ctx, \"GET\", downloadURL, nil)\nif err != nil {\n    return nil, fmt.Errorf(\"创建下载链接请求失败: %w\", err)\n}","handlingStrategy":"validation","validationCode":"u, err := url.Parse(downloadURL)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"跳过无效下载链接: %q\", downloadURL)\n}","typeGuard":null,"tryCatchPattern":"links, err := getDownloadLinks(ctx, post)\nif err != nil && strings.Contains(err.Error(), \"创建下载链接请求失败\") {\n    // invalid URL from this post: skip it and continue with other results\n}","preventionTips":["Validate post link fields (absolute URL with scheme/host) before fetching download pages","Skip rather than fail the entire batch when one result has a bad link","Sanitize/escape path segments derived from post data","Log the offending URL so upstream field changes are caught quickly"],"tags":["http","url","request-construction","go"],"backgroundTag":"invalid-url","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"}