{"record":{"id":"31b4360142af8948","repo":"fish2018/pansou","slug":"s-w-31b436","errorCode":null,"errorMessage":"[%s] 创建搜索请求失败: %w","messagePattern":"\\[(.+?)\\] 创建搜索请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/5266ys/5266ys.go","lineNumber":176,"sourceCode":"\t\t\t}\n\t\t}()\n\t}\n\twg.Wait()\n\n\treturn plugin.FilterResultsByKeyword(results, keyword), nil\n}\n\nfunc (p *Plugin) fetchSearch(client *http.Client, keyword string) (*goquery.Document, error) {\n\tencoded, err := encodeGB18030(keyword)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 编码搜索关键词失败: %w\", p.Name(), err)\n\t}\n\tform := \"show=title%2Csmalltext&tempid=1&tbname=article&keyboard=\" + url.QueryEscape(string(encoded)) + \"&submit=\"\n\tctx, cancel := context.WithTimeout(context.Background(), requestTimeout)\n\tdefer cancel()\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, baseURL+searchPath, strings.NewReader(form))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 创建搜索请求失败: %w\", p.Name(), err)\n\t}\n\tsetHeaders(req, baseURL+\"/\")\n\treq.Header.Set(\"Content-Type\", \"application/x-www-form-urlencoded\")\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err)\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求返回 HTTP %d\", p.Name(), resp.StatusCode)\n\t}\n\tbody, err := io.ReadAll(io.LimitReader(resp.Body, 4<<20))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 读取搜索结果失败: %w\", p.Name(), err)\n\t}\n\tdecoded, err := decodeGB18030(body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 解码搜索结果失败: %w\", p.Name(), err)","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/5266ys/5266ys.go#L158-L194","documentation":"The 5266ys plugin's fetchSearch wraps any error returned by http.NewRequestWithContext when building the POST request to the site's search endpoint. This fires when the HTTP method, URL (baseURL+searchPath), or body reader is invalid per net/http's request validation (e.g. unparseable URL, invalid method characters). Because baseURL/searchPath are plugin constants and the body is a strings.Reader, this almost never fires at runtime.","triggerScenarios":"http.NewRequestWithContext returns a non-nil err — typically only when baseURL+searchPath does not parse as a valid URL (e.g. a misconfigured/blank baseURL with spaces or control characters) or the method string is malformed.","commonSituations":"A developer changed baseURL/searchPath constants and introduced a typo, whitespace, or a missing scheme; an environment where baseURL is injected from config and contains an invalid value; hand-editing the searchPath constant and breaking URL syntax.","solutions":["Inspect and fix the baseURL/searchPath constants in plugin/5266ys/5266ys.go so their concatenation is an absolute, well-formed URL (scheme + host + path).","Check the wrapped %w error message — net/http names the exact offending field (e.g. 'net/http: nil Context' or 'invalid method').","Log baseURL+searchPath before the call to confirm no spaces, newlines, or missing scheme.","If baseURL comes from configuration, validate it with url.Parse at plugin startup instead of failing per-request."],"exampleFix":"// before\nbaseURL := \"\" // misconfigured, empty\nreq, err := http.NewRequestWithContext(ctx, http.MethodPost, baseURL+searchPath, strings.NewReader(form))\nif err != nil {\n    return nil, fmt.Errorf(\"[%s] 创建搜索请求失败: %w\", p.Name(), err)\n}\n// after\nu, perr := url.Parse(baseURL)\nif perr != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return nil, fmt.Errorf(\"[%s] 无效的站点地址: %q\", p.Name(), baseURL)\n}\nreq, err := http.NewRequestWithContext(ctx, http.MethodPost, baseURL+searchPath, strings.NewReader(form))\nif err != nil {\n    return nil, fmt.Errorf(\"[%s] 创建搜索请求失败: %w\", p.Name(), err)\n}","handlingStrategy":"validation","validationCode":"u, err := url.Parse(baseURL + searchPath)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    // skip/fix before calling search\n    return nil, fmt.Errorf(\"无效站点URL: %q\", baseURL+searchPath)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep baseURL/searchPath as validated constants; never interpolate untrusted config without url.Parse.","Validate the site URL once at plugin init, not per request.","Fail fast at startup if the configured site URL is unreachable or malformed."],"tags":["go","http","url"],"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"}