fish2018/pansou · error
[ ] 创建请求失败
Error message
[%s] 创建请求失败: %w
What it means
Returned by doSearch in the aikanzy plugin when http.NewRequestWithContext fails to construct the GET request for the search URL. This happens before any network I/O and almost always means the URL string is malformed (parse error), since method/body are constant. The construction error is wrapped with %w.
Solutions
- Log/print the searchURL on failure to spot the malformed URL.
- Ensure the base URL includes a valid scheme (https://) and host.
- Escape the keyword with url.QueryEscape before appending it to the URL.
- Validate the final URL with url.Parse before calling http.NewRequestWithContext.
Example fix
// before
searchURL := baseURL + "/search/" + keyword
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
// after
searchURL := baseURL + "/search/" + url.QueryEscape(keyword)
if _, perr := neturl.Parse(searchURL); perr != nil {
return nil, fmt.Errorf("invalid search URL %q: %w", searchURL, perr)
}
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil) Defensive patterns
Strategy: validation
Validate before calling
u, err := neturl.Parse(searchURL)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("invalid search URL: %q", searchURL)
}
// ensure keyword is escaped: url.QueryEscape(keyword) Try / catch
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
log.Printf("request build failed for URL %q: %v", searchURL, err)
return err
} Prevention
- Always validate configured base URLs (scheme + host) at startup.
- Use url.Values or url.QueryEscape for all user-supplied query terms.
- Reject empty/whitespace keywords before building the URL.
- Unit-test URL construction with special characters (%, &, spaces, CJK).
When it happens
Trigger: p.doSearch builds searchURL (base URL + query params) and passes it to http.NewRequestWithContext; http.NewRequest returns an error because the URL cannot be parsed (e.g. control characters, bad scheme, unescaped invalid chars from user keyword interpolation).
Common situations: The configured base URL has a typo (missing scheme like 'https://'); the search keyword contains characters that were not url.QueryEscape'd; an env/config override sets an empty or invalid URL.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/fab3cea5b26a1684.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/aikanzy/aikanzy.go:147
// 使用优化的客户端
if p.optimizedClient != nil {
client = p.optimizedClient
}
// 对关键词进行URL编码
encodedKeyword := url.QueryEscape(keyword)
// 构建搜索URL
searchURL := fmt.Sprintf(searchURLTemplate, encodedKeyword)
// 创建一个带有超时的上下文
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout*time.Second)
defer cancel()
// 创建请求
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
}
// 设置完整的请求头(避免反爬虫)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
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("Referer", "https://www.aikanzy.com/")
req.Header.Set("Upgrade-Insecure-Requests", "1")
req.Header.Set("Cache-Control", "max-age=0")
// 使用带重试的请求方法发送HTTP请求
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return nil, fmt.Errorf("[%s] 请求搜索页面失败: %w", p.Name(), err)
}
defer resp.Body.Close()
View on GitHub (pinned to beaa561337)