{"record":{"id":"75cae64ba1378eb9","repo":"fish2018/pansou","slug":"s-w-75cae6","errorCode":null,"errorMessage":"[%s] 创建请求失败: %w","messagePattern":"\\[(.+?)\\] 创建请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/huban/huban.go","lineNumber":251,"sourceCode":"\n\t// 8. 异步获取详情页信息\n\tenhancedResults := p.enhanceWithDetails(client, results, selectedBase)\n\n\t// 9. 关键词过滤\n\treturn plugin.FilterResultsByKeyword(enhancedResults, keyword), nil\n}\n\nfunc (p *HubanAsyncPlugin) searchAtBase(client *http.Client, keyword, baseURL string) ([]model.SearchResult, error) {\n\tsearchURL := fmt.Sprintf(\"%s/index.php/vod/search/wd/%s.html\", strings.TrimRight(baseURL, \"/\"), url.QueryEscape(keyword))\n\n\t// 2. 创建带超时的上下文\n\tctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout)\n\tdefer cancel()\n\n\t// 3. 创建请求\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 创建请求失败: %w\", p.Name(), err)\n\t}\n\n\t// 4. 设置请求头\n\treq.Header.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36\")\n\treq.Header.Set(\"Accept\", \"text/html,application/xhtml+xml,application/xml;q=0.9,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(\"Connection\", \"keep-alive\")\n\treq.Header.Set(\"Referer\", strings.TrimRight(baseURL, \"/\")+\"/\")\n\n\t// 5. 发送请求\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求返回状态码: %d\", p.Name(), resp.StatusCode)","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/huban/huban.go#L233-L269","documentation":"In searchAtBase, http.NewRequestWithContext failed while constructing the GET request for the search URL on a given mirror base. Like any NewRequest failure this is a malformed-URL / invalid-argument problem, not a network problem.","triggerScenarios":"searchURL built from a base URL plus query parameters contains invalid characters (unescaped Chinese keywords, spaces, control characters) or the base URL itself is malformed, causing http.NewRequestWithContext to reject it.","commonSituations":"Keyword containing spaces or special characters interpolated without url.QueryEscape; a stale/malformed mirror base in the config; corrupted encoding of the keyword.","solutions":["Escape query parameters with url.QueryEscape(keyword) before building searchURL.","Validate the base URL with url.Parse and skip/reject malformed mirrors.","Log searchURL on failure to see the exact malformed value.","Ensure the keyword string is valid UTF-8 and free of control characters."],"exampleFix":"// before\nsearchURL := baseURL + \"/search.php?keyword=\" + keyword\nreq, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)\n// after\nsearchURL := baseURL + \"/search.php?keyword=\" + url.QueryEscape(keyword)\nreq, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)","handlingStrategy":"validation","validationCode":"u, err := url.Parse(baseURL)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid mirror base: %q\", baseURL)\n}\nsearchURL := *u\nsearchURL.Path = path.Join(u.Path, \"search.php\")\nq := searchURL.Query()\nq.Set(\"keyword\", keyword) // QueryEscape handled by Values.Encode\nsearchURL.RawQuery = q.Encode()","typeGuard":"func isValidURL(s string) bool {\n    u, err := url.Parse(s)\n    return err == nil && u.Scheme != \"\" && u.Host != \"\"\n}","tryCatchPattern":"results, err := p.Search(keyword, ext)\nif err != nil {\n    if strings.Contains(err.Error(), \"创建请求失败\") {\n        return errors.New(\"search URL construction failed — check keyword encoding / mirror base\")\n    }\n    return err\n}","preventionTips":["Always build query strings with url.Values / url.QueryEscape, never string concat","Validate mirror base URLs at config-load time","Reject keywords with control characters before search","Log the full URL on construction failure"],"tags":["http","url","encoding","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"}