{"record":{"id":"69bbd9101c9f158c","repo":"fish2018/pansou","slug":"s-d-w-69bbd9","errorCode":null,"errorMessage":"[%s] 创建第%d页请求失败: %w","messagePattern":"\\[(.+?)\\] 创建第(.+?)页请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/yunsou/yunsou.go","lineNumber":121,"sourceCode":"\t\t}\n\t\tresults = append(results, p.parseSearchResults(pageDoc)...)\n\t}\n\tif len(results) > maxResults {\n\t\tresults = results[:maxResults]\n\t}\n\treturn plugin.FilterResultsByKeyword(results, keyword), nil\n}\n\nfunc (p *YunsouAsyncPlugin) fetchPage(ctx context.Context, client *http.Client, keyword string, page int) (*goquery.Document, error) {\n\tpathKeyword := url.PathEscape(keyword)\n\tpath := pathKeyword\n\tif page > 1 {\n\t\tpath = fmt.Sprintf(\"%s-%d\", pathKeyword, page)\n\t}\n\trequestURL := fmt.Sprintf(searchURLTemplate, path)\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, requestURL, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 创建第%d页请求失败: %w\", p.Name(), page, err)\n\t}\n\treq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36\")\n\treq.Header.Set(\"Accept\", \"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\")\n\treq.Header.Set(\"Accept-Language\", \"zh-CN,zh;q=0.9,en;q=0.8\")\n\treq.Header.Set(\"Referer\", \"https://wpys.cc/\")\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 第%d页搜索请求失败: %w\", p.Name(), page, err)\n\t}\n\tdefer resp.Body.Close()\n\tdoc, err := goquery.NewDocumentFromReader(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 解析第%d页失败: %w\", p.Name(), page, err)\n\t}\n\treturn doc, nil\n}\n\nfunc (p *YunsouAsyncPlugin) doRequestWithRetry(req *http.Request, client *http.Client) (*http.Response, error) {","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/yunsou/yunsou.go#L103-L139","documentation":"fetchPage in the yunsou plugin failed while constructing the GET request for a search results page via http.NewRequestWithContext. The error is prefixed with the plugin name and page number. Since the URL is built from a template with a keyword-derived path, this usually means the URL is malformed (e.g. special characters in the keyword path) or the context is already canceled.","triggerScenarios":"http.NewRequestWithContext fails building the request to searchURLTemplate with pathKeyword (and -page suffix) — invalid URL characters from an unescaped keyword, or an invalid/canceled ctx.","commonSituations":"Keywords containing spaces, slashes, or CJK characters placed into a path without escaping; a canceled parent context; a mistyped searchURLTemplate constant.","solutions":["URL-escape pathKeyword with url.PathEscape before formatting into the template","Log requestURL on failure to spot malformed construction","Check ctx.Err() before building the request","Validate searchURLTemplate is a valid absolute URL"],"exampleFix":"// before\npath = fmt.Sprintf(\"%s-%d\", pathKeyword, page)\nrequestURL := fmt.Sprintf(searchURLTemplate, path)\nreq, err := http.NewRequestWithContext(ctx, http.MethodGet, requestURL, nil)\nif err != nil {\n    return nil, fmt.Errorf(\"[%s] 创建第%d页请求失败: %w\", p.Name(), page, err)\n}\n// after\npath = fmt.Sprintf(\"%s-%d\", url.PathEscape(pathKeyword), page)\nrequestURL := fmt.Sprintf(searchURLTemplate, path)\nif _, perr := url.Parse(requestURL); perr != nil {\n    return nil, fmt.Errorf(\"[%s] invalid page %d url %q: %w\", p.Name(), page, requestURL, perr)\n}\nreq, err := http.NewRequestWithContext(ctx, http.MethodGet, requestURL, nil)\nif err != nil {\n    return nil, fmt.Errorf(\"[%s] 创建第%d页请求失败: %w\", p.Name(), page, err)\n}","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(pathKeyword) == \"\" {\n    return errors.New(\"keyword path required\")\n}\nesccaped := url.PathEscape(pathKeyword)\nrequestURL := fmt.Sprintf(searchURLTemplate, esccaped)\nif _, err := url.Parse(requestURL); err != nil {\n    return fmt.Errorf(\"invalid request url: %w\", err)\n}","typeGuard":"func validURL(s string) bool {\n    u, err := url.Parse(s)\n    return err == nil && u.Scheme != \"\" && u.Host != \"\"\n}","tryCatchPattern":"items, err := fetchPage(ctx, client, keyword, page)\nif err != nil && strings.Contains(err.Error(), \"创建第\") {\n    log.Error(\"yunsou page request construction failed\", \"page\", page, \"err\", err)\n    return nil, err\n}","preventionTips":["Always url.PathEscape keyword-derived path segments","Log the fully built URL on construction failure","Check ctx.Err() before building requests","Validate URL templates at startup with a dry-run parse"],"tags":["http","url","request-construction","escaping"],"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"}