fish2018/pansou · error
[ ] 创建搜索请求失败
Error message
[%s] 创建搜索请求失败: %w
What it means
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.
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.
Example fix
// before
baseURL := "" // misconfigured, empty
req, err := http.NewRequestWithContext(ctx, http.MethodPost, baseURL+searchPath, strings.NewReader(form))
if err != nil {
return nil, fmt.Errorf("[%s] 创建搜索请求失败: %w", p.Name(), err)
}
// after
u, perr := url.Parse(baseURL)
if perr != nil || u.Scheme == "" || u.Host == "" {
return nil, fmt.Errorf("[%s] 无效的站点地址: %q", p.Name(), baseURL)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, baseURL+searchPath, strings.NewReader(form))
if err != nil {
return nil, fmt.Errorf("[%s] 创建搜索请求失败: %w", p.Name(), err)
} Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(baseURL + searchPath)
if err != nil || u.Scheme == "" || u.Host == "" {
// skip/fix before calling search
return nil, fmt.Errorf("无效站点URL: %q", baseURL+searchPath)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
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/31b4360142af8948.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/5266ys/5266ys.go:176
}
}()
}
wg.Wait()
return plugin.FilterResultsByKeyword(results, keyword), nil
}
func (p *Plugin) fetchSearch(client *http.Client, keyword string) (*goquery.Document, error) {
encoded, err := encodeGB18030(keyword)
if err != nil {
return nil, fmt.Errorf("[%s] 编码搜索关键词失败: %w", p.Name(), err)
}
form := "show=title%2Csmalltext&tempid=1&tbname=article&keyboard=" + url.QueryEscape(string(encoded)) + "&submit="
ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, baseURL+searchPath, strings.NewReader(form))
if err != nil {
return nil, fmt.Errorf("[%s] 创建搜索请求失败: %w", p.Name(), err)
}
setHeaders(req, baseURL+"/")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("[%s] 搜索请求返回 HTTP %d", p.Name(), resp.StatusCode)
}
body, err := io.ReadAll(io.LimitReader(resp.Body, 4<<20))
if err != nil {
return nil, fmt.Errorf("[%s] 读取搜索结果失败: %w", p.Name(), err)
}
decoded, err := decodeGB18030(body)
if err != nil {
return nil, fmt.Errorf("[%s] 解码搜索结果失败: %w", p.Name(), err)View on GitHub (pinned to beaa561337)