{"record":{"id":"3701a1481e320e5f","repo":"fish2018/pansou","slug":"w-3701a1","errorCode":null,"errorMessage":"创建请求失败: %w","messagePattern":"创建请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/susu/susu.go","lineNumber":151,"sourceCode":"}\n\n// SearchWithResult 执行搜索并返回包含IsFinal标记的结果\nfunc (p *SusuAsyncPlugin) SearchWithResult(keyword string, ext map[string]interface{}) (model.PluginSearchResult, error) {\n\treturn p.AsyncSearchWithResult(keyword, p.doSearch, p.MainCacheKey, ext)\n}\n\n// doSearch 实际的搜索实现\nfunc (p *SusuAsyncPlugin) doSearch(client *http.Client, keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {\n\t// 构建搜索URL\n\tsearchURL := fmt.Sprintf(SearchURL, url.QueryEscape(keyword))\n\n\t// 发送请求\n\tctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n\tdefer cancel()\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, searchURL, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"创建请求失败: %w\", err)\n\t}\n\n\t// 设置请求头\n\treq.Header.Set(\"User-Agent\", getRandomUA())\n\tsetBrowserHeaders(req, BaseURL+\"/\")\n\n\t// 发送请求（带重试）\n\tresp, err := p.doRequestWithRetry(client, req, MaxRetries)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"请求失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"[susu] 搜索请求返回状态码: %d\", resp.StatusCode)\n\t}\n\n\t// 解析HTML\n\tdoc, err := goquery.NewDocumentFromReader(resp.Body)","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/susu/susu.go#L133-L169","documentation":"doSearch builds a GET request to the susu search URL with a 30s context; if http.NewRequestWithContext returns an error, it is wrapped as 创建请求失败 (request creation failed). In Go this only happens for an invalid method/URL or a nil/already-done context — here essentially always a malformed searchURL.","triggerScenarios":"searchURL is malformed: BaseURL is misconfigured (invalid scheme/host) or the query string built from the keyword contains unescaped invalid characters.","commonSituations":"Typo'd or empty BaseURL constant; keyword with raw spaces or special characters interpolated without url.QueryEscape; configuration injection of a bad proxy/base URL.","solutions":["Build the query with url.Values.Encode() so the keyword is properly escaped","Print searchURL on failure to identify the malformed part and fix BaseURL or keyword encoding","Validate BaseURL with url.Parse at plugin startup to fail fast"],"exampleFix":"// before\nsearchURL := BaseURL + \"/search?keyword=\" + keyword\nreq, err := http.NewRequestWithContext(ctx, http.MethodGet, searchURL, nil)\nif err != nil {\n    return nil, fmt.Errorf(\"创建请求失败: %w\", err)\n}\n// after\nsearchURL := BaseURL + \"/search?\" + url.Values{\"keyword\": {keyword}}.Encode()\nreq, err := http.NewRequestWithContext(ctx, http.MethodGet, searchURL, nil)\nif err != nil {\n    return nil, fmt.Errorf(\"创建请求失败 (url=%s): %w\", searchURL, err)\n}","handlingStrategy":"validation","validationCode":"u, err := url.Parse(searchURL)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid searchURL %q\", searchURL)\n}","typeGuard":null,"tryCatchPattern":"results, err := doSearch(keyword)\nif err != nil && strings.Contains(err.Error(), \"创建请求失败\") {\n    return fmt.Errorf(\"check BaseURL and keyword encoding: %w\", err)\n}","preventionTips":["Build query strings with url.Values.Encode() instead of string concatenation","Validate BaseURL at startup with url.Parse","Include the offending URL in the wrapped error for diagnosis"],"tags":["http","url","encoding"],"backgroundTag":"invalid-url-format","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"}