fish2018/pansou · error
[ ] 创建请求失败
Error message
[%s] 创建请求失败: %w
What it means
http.NewRequestWithContext failed while building the GET request for the pianku search URL, so the request was never sent. This only happens with an invalid method/URL/body combination — most commonly a malformed searchURL.
Solutions
- Log the constructed searchURL when this error occurs
- Validate/escape the keyword with url.QueryEscape before building the URL
- Sanity-check the configured base URL (scheme, no whitespace)
- If the base URL comes from config, add a startup validation step
Example fix
// before
searchURL := baseURL + "/s.php?q=" + keyword
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
// after
searchURL := baseURL + "/s.php?q=" + url.QueryEscape(keyword)
if _, perr := url.Parse(searchURL); perr != nil { return nil, fmt.Errorf("bad search url %q: %w", searchURL, perr) }
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil) Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(searchURL)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("invalid search URL %q", searchURL)
} Type guard
func validURL(s string) bool {
u, err := url.Parse(s)
return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
} Try / catch
results, err := plugin.Search(keyword, ext)
if err != nil {
if strings.Contains(err.Error(), "创建请求失败") {
// malformed URL/config: fix base URL or keyword escaping, do not retry
}
} Prevention
- Escape keywords with url.QueryEscape
- Validate configured base URLs at startup
- Never interpolate untrusted input into URL strings without escaping
When it happens
Trigger: searchURL built from config/base URL that is unparseable (control characters, missing scheme, bad query escaping of the keyword), causing url.Parse to fail inside NewRequestWithContext.
Common situations: Misconfigured base URL containing spaces or newlines; keyword with characters that break naive URL concatenation; empty base URL variable in config.
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/1ec7ac05a2efc1a1.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/pianku/pianku.go:132
if ext != nil {
if titleEn, exists := ext["title_en"]; exists {
if titleEnStr, ok := titleEn.(string); ok && titleEnStr != "" {
searchKeyword = titleEnStr
}
}
}
// 构建请求URL
searchURL := fmt.Sprintf("%s%s?wd=%s", BaseURL, SearchPath, url.QueryEscape(searchKeyword))
// 创建带超时的上下文
ctx, cancel := context.WithTimeout(context.Background(), TimeoutSeconds*time.Second)
defer cancel()
// 创建请求
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
}
// 设置请求头
p.setRequestHeaders(req)
// 发送HTTP请求(带重试机制)
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
defer resp.Body.Close()
// 检查状态码
if resp.StatusCode != 200 {
return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// 解析HTMLView on GitHub (pinned to beaa561337)