fish2018/pansou · error
创建请求失败
Error message
创建请求失败: %w
What it means
In fetchSearchResults, http.NewRequestWithContext failed to construct the GET request for the search URL. This happens before any network I/O and usually means the URL is malformed (unparsable scheme/host) — often because keyword interpolation produced an invalid URL.
Solutions
- Validate cygBaseURL starts with http:// or https:// and is a parseable URL before building the request.
- Ensure url.QueryEscape is applied to the keyword (it is) and that no raw control characters enter the URL.
- Print the final searchURL on failure to spot malformed construction.
- Use url.Parse on the final URL as a pre-check and fail early with a clearer message.
Example fix
// before
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
return nil, fmt.Errorf("创建请求失败: %w", err)
}
// after
if u, perr := url.Parse(searchURL); perr != nil || u.Scheme == "" || u.Host == "" {
return nil, fmt.Errorf("无效的搜索URL: %q (%v)", searchURL, perr)
}
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
return nil, fmt.Errorf("创建请求失败: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(baseURL)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("cygBaseURL 无效: %q", baseURL)
} Try / catch
results, err := plugin.SearchWithResult(ctx, opts)
if err != nil && strings.Contains(err.Error(), "创建请求失败") {
// configuration problem: check baseURL format before retrying
} Prevention
- Validate the base URL (scheme + host) at config load time, not at request time
- Reject empty or scheme-less URLs in configuration
- Keep url.QueryEscape on all user-derived query values
When it happens
Trigger: searchImpl passes a searchURL built from cygBaseURL plus query params that http.NewRequestWithContext cannot parse — e.g. empty base URL, control characters in the keyword that survived QueryEscape, or a malformed base URL configuration.
Common situations: cygBaseURL configured without a scheme (missing https://) or with a typo; keyword containing newlines or control characters; empty configuration making the URL just the query string.
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/8a724d7c46b9a93c.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/cyg/cyg.go:140
// 3. 并发获取每个帖子的下载链接
results := p.fetchDownloadLinksAsync(client, posts, keyword)
// 4. 关键词过滤
filteredResults := plugin.FilterResultsByKeyword(results, keyword)
return filteredResults, nil
}
// fetchSearchResults 获取搜索结果列表
func (p *CygPlugin) fetchSearchResults(client *http.Client, searchURL string) ([]CygPost, error) {
// 创建带超时的上下文
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// 创建请求对象
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
return nil, fmt.Errorf("创建请求失败: %w", err)
}
// 设置请求头
p.setRequestHeaders(req)
// 发送请求
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return nil, fmt.Errorf("HTTP请求失败: %w", err)
}
defer resp.Body.Close()
// 检查状态码
if resp.StatusCode != 200 {
return nil, fmt.Errorf("HTTP错误状态码: %d", resp.StatusCode)
}
// 解析响应View on GitHub (pinned to beaa561337)