fish2018/pansou · error
创建请求失败
Error message
创建请求失败: %w
What it means
doSearch builds a GET request to the susu search URL with a 30s context; if http.NewRequestWithContext returns an error, it is wrapped as 创建请求失败 (request creation failed). In Go this only happens for an invalid method/URL or a nil/already-done context — here essentially always a malformed searchURL.
Solutions
- Build the query with url.Values.Encode() so the keyword is properly escaped
- Print searchURL on failure to identify the malformed part and fix BaseURL or keyword encoding
- Validate BaseURL with url.Parse at plugin startup to fail fast
Example fix
// before
searchURL := BaseURL + "/search?keyword=" + keyword
req, err := http.NewRequestWithContext(ctx, http.MethodGet, searchURL, nil)
if err != nil {
return nil, fmt.Errorf("创建请求失败: %w", err)
}
// after
searchURL := BaseURL + "/search?" + url.Values{"keyword": {keyword}}.Encode()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, searchURL, nil)
if err != nil {
return nil, fmt.Errorf("创建请求失败 (url=%s): %w", searchURL, err)
} Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(searchURL)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("invalid searchURL %q", searchURL)
} Try / catch
results, err := doSearch(keyword)
if err != nil && strings.Contains(err.Error(), "创建请求失败") {
return fmt.Errorf("check BaseURL and keyword encoding: %w", err)
} Prevention
- Build query strings with url.Values.Encode() instead of string concatenation
- Validate BaseURL at startup with url.Parse
- Include the offending URL in the wrapped error for diagnosis
When it happens
Trigger: searchURL is malformed: BaseURL is misconfigured (invalid scheme/host) or the query string built from the keyword contains unescaped invalid characters.
Common situations: Typo'd or empty BaseURL constant; keyword with raw spaces or special characters interpolated without url.QueryEscape; configuration injection of a bad proxy/base 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/3701a1481e320e5f.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/susu/susu.go:151
}
// SearchWithResult 执行搜索并返回包含IsFinal标记的结果
func (p *SusuAsyncPlugin) SearchWithResult(keyword string, ext map[string]interface{}) (model.PluginSearchResult, error) {
return p.AsyncSearchWithResult(keyword, p.doSearch, p.MainCacheKey, ext)
}
// doSearch 实际的搜索实现
func (p *SusuAsyncPlugin) doSearch(client *http.Client, keyword string, ext map[string]interface{}) ([]model.SearchResult, error) {
// 构建搜索URL
searchURL := fmt.Sprintf(SearchURL, url.QueryEscape(keyword))
// 发送请求
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, searchURL, nil)
if err != nil {
return nil, fmt.Errorf("创建请求失败: %w", err)
}
// 设置请求头
req.Header.Set("User-Agent", getRandomUA())
setBrowserHeaders(req, BaseURL+"/")
// 发送请求(带重试)
resp, err := p.doRequestWithRetry(client, req, MaxRetries)
if err != nil {
return nil, fmt.Errorf("请求失败: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("[susu] 搜索请求返回状态码: %d", resp.StatusCode)
}
// 解析HTML
doc, err := goquery.NewDocumentFromReader(resp.Body)View on GitHub (pinned to beaa561337)