fish2018/pansou · error
[ ] 创建搜索请求失败
Error message
[%s] 创建搜索请求失败: %w
What it means
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.
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
Example fix
// before
searchURL := BaseURL + "/search?q=" + keyword
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
// after
searchURL := BaseURL + "/search?" + url.Values{"q": {keyword}}.Encode()
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil) Defensive patterns
Strategy: validation
Validate before calling
if _, err := url.Parse(searchURL); err != nil {
return fmt.Errorf("invalid search URL %q: %w", searchURL, err)
} Type guard
func validURL(raw string) bool {
u, err := url.Parse(raw)
return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
} Try / catch
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
return nil, fmt.Errorf("[%s] 创建搜索请求失败: %w", p.Name(), err)
} Prevention
- 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
When it happens
Trigger: http.NewRequestWithContext(ctx, "GET", searchURL, nil) returned err — i.e. searchURL contains control characters, invalid percent-encodings, or is empty/unparsable.
Common situations: 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.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/736d1ee75d1e59a0.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/dyyj/dyyj.go:241
// use if the forum API changes or becomes unavailable.
func (p *DyyjPlugin) executeSearchHTML(client *http.Client, keyword string) ([]model.SearchResult, error) {
// 构建搜索URL
searchURL := fmt.Sprintf("%s%s", BaseURL, fmt.Sprintf(SearchPath, url.QueryEscape(keyword)))
if p.debugMode {
log.Printf("[DYYJ] 搜索URL: %s", searchURL)
}
// 创建带超时的上下文
ctx, cancel := context.WithTimeout(context.Background(), RequestTimeout)
defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
if p.debugMode {
log.Printf("[DYYJ] 创建搜索请求失败: %v", err)
}
return nil, fmt.Errorf("[%s] 创建搜索请求失败: %w", p.Name(), err)
}
// 设置完整的请求头
req.Header.Set("User-Agent", UserAgent)
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Upgrade-Insecure-Requests", "1")
req.Header.Set("Cache-Control", "max-age=0")
req.Header.Set("Referer", BaseURL+"/")
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
if p.debugMode {
log.Printf("[DYYJ] 搜索请求失败: %v", err)
}
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}View on GitHub (pinned to beaa561337)