{"record":{"id":"736d1ee75d1e59a0","repo":"fish2018/pansou","slug":"s-w-736d1e","errorCode":null,"errorMessage":"[%s] 创建搜索请求失败: %w","messagePattern":"\\[(.+?)\\] 创建搜索请求失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/dyyj/dyyj.go","lineNumber":241,"sourceCode":"// use if the forum API changes or becomes unavailable.\nfunc (p *DyyjPlugin) executeSearchHTML(client *http.Client, keyword string) ([]model.SearchResult, error) {\n\t// 构建搜索URL\n\tsearchURL := fmt.Sprintf(\"%s%s\", BaseURL, fmt.Sprintf(SearchPath, url.QueryEscape(keyword)))\n\n\tif p.debugMode {\n\t\tlog.Printf(\"[DYYJ] 搜索URL: %s\", searchURL)\n\t}\n\n\t// 创建带超时的上下文\n\tctx, cancel := context.WithTimeout(context.Background(), RequestTimeout)\n\tdefer cancel()\n\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)\n\tif err != nil {\n\t\tif p.debugMode {\n\t\t\tlog.Printf(\"[DYYJ] 创建搜索请求失败: %v\", err)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"[%s] 创建搜索请求失败: %w\", p.Name(), err)\n\t}\n\n\t// 设置完整的请求头\n\treq.Header.Set(\"User-Agent\", UserAgent)\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(\"Upgrade-Insecure-Requests\", \"1\")\n\treq.Header.Set(\"Cache-Control\", \"max-age=0\")\n\treq.Header.Set(\"Referer\", BaseURL+\"/\")\n\n\tresp, err := p.doRequestWithRetry(req, client)\n\tif err != nil {\n\t\tif p.debugMode {\n\t\t\tlog.Printf(\"[DYYJ] 搜索请求失败: %v\", err)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"[%s] 搜索请求失败: %w\", p.Name(), err)\n\t}","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/dyyj/dyyj.go#L223-L259","documentation":"dyyj.executeSearchHTML could not construct the outbound *http.Request via http.NewRequestWithContext. This almost always means the searchURL failed URL parsing (url.Parse error). Rare, since searchURL is built from constants, but thrown defensively.","triggerScenarios":"http.NewRequestWithContext(ctx, \"GET\", searchURL, nil) returned err — i.e. searchURL contains control characters, invalid percent-encodings, or is empty/unparsable.","commonSituations":"A configuration or constant BaseURL/search path was edited to include spaces or unescaped characters; keyword interpolation broke URL escaping; env-specific override of the site URL is malformed.","solutions":["Print searchURL before the call and run url.Parse on it to see the exact parse error","Ensure the keyword is escaped with url.QueryEscape / url.Values.Encode() before interpolation","Fix the BaseURL/search-path constant — remove spaces, control chars, or bad %-sequences","Validate configured site URLs at plugin startup"],"exampleFix":"// before\nsearchURL := BaseURL + \"/search?q=\" + keyword\nreq, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)\n// after\nsearchURL := BaseURL + \"/search?\" + url.Values{\"q\": {keyword}}.Encode()\nreq, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)","handlingStrategy":"validation","validationCode":"if _, err := url.Parse(searchURL); err != nil {\n\treturn fmt.Errorf(\"invalid search URL %q: %w\", searchURL, err)\n}","typeGuard":"func validURL(raw string) bool {\n\tu, err := url.Parse(raw)\n\treturn err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\") && u.Host != \"\"\n}","tryCatchPattern":"req, err := http.NewRequestWithContext(ctx, \"GET\", searchURL, nil)\nif err != nil {\n\treturn nil, fmt.Errorf(\"[%s] 创建搜索请求失败: %w\", p.Name(), err)\n}","preventionTips":["Always build URLs with url.Values.Encode() instead of string concatenation","Validate BaseURL and site constants at plugin startup","Escape keywords with url.QueryEscape","Strip control characters from user input before URL composition"],"tags":["go","http","url-parsing"],"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"}