fish2018/pansou · error
创建详情页请求失败
Error message
创建详情页请求失败: %w
What it means
In WujiPlugin.fetchMagnetLink the plugin builds a GET request for the detail page with http.NewRequestWithContext under a TimeoutSeconds timeout. This error wraps any failure of http.NewRequestWithContext itself — it fires before any network I/O happens. Typical causes are a malformed/unparseable detailURL, an unsupported URL scheme, or a nil/invalid context.
Solutions
- Log the detailURL value when this error occurs and inspect it for emptiness, spaces, or missing scheme.
- Resolve scraped hrefs against the site base before calling fetchMagnetLink, e.g. resp.Request.URL.Parse(href) or url.Parse + ResolveReference.
- Validate the URL with url.ParseRequestURI(detailURL) and skip results with invalid links instead of letting the error propagate.
- Skip enrichment for a result whose Links slice is empty (enrichWithMagnetLinks already checks len(Links)==0; make sure the link value itself is non-empty too).
Example fix
// before
magnet, err := p.fetchMagnetLink(client, link.Href)
// after
u, perr := url.Parse(strings.TrimSpace(link.Href))
if perr != nil || u.Scheme == "" {
continue // skip invalid detail URL
}
magnet, err := p.fetchMagnetLink(client, base.ResolveReference(u).String()) Defensive patterns
Strategy: validation
Validate before calling
u, err := url.ParseRequestURI(strings.TrimSpace(detailURL))
if err != nil || (u.Scheme != "http" && u.Scheme != "https") {
// skip this result; don't call fetchMagnetLink
} Try / catch
magnet, err := p.fetchMagnetLink(client, detailURL)
if err != nil {
log.Printf("magnet fetch failed for %s: %v", detailURL, err)
return ""
} Prevention
- Always resolve scraped hrefs against the site base URL before use
- Trim whitespace and URL-encode paths extracted from HTML attributes
- Skip results with empty or scheme-less links instead of attempting enrichment
When it happens
Trigger: fetchMagnetLink is called with a detailURL that http.NewRequestWithContext cannot parse: empty string, missing scheme, invalid characters, control characters in the URL, or a non-http(s) scheme. Also fires if the timeout context is already invalid.
Common situations: Scraped hrefs from search results that are empty or relative and never resolved against the site base URL; detail URLs containing spaces or unencoded Chinese characters taken straight from HTML attributes; site layout change producing href="" for every result.
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/672bb229a13c2d82.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/wuji/wuji.go:308
// 检查缓存
if cached, ok := magnetCache.Load(detailURL); ok {
if entry, ok := cached.(magnetCacheEntry); ok {
if time.Since(entry.Timestamp) < cacheTTL {
// 缓存命中
return entry.MagnetLink, nil
}
// 缓存过期,删除
magnetCache.Delete(detailURL)
}
}
// 创建带超时的上下文
ctx, cancel := context.WithTimeout(context.Background(), TimeoutSeconds*time.Second)
defer cancel()
// 创建请求
req, err := http.NewRequestWithContext(ctx, "GET", detailURL, nil)
if err != nil {
return "", fmt.Errorf("创建详情页请求失败: %w", err)
}
// 设置请求头
p.setRequestHeaders(req)
// 发送HTTP请求
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return "", fmt.Errorf("详情页请求失败: %w", err)
}
defer resp.Body.Close()
// 检查状态码
if resp.StatusCode != 200 {
return "", fmt.Errorf("详情页返回状态码: %d", resp.StatusCode)
}
// 读取响应体内容View on GitHub (pinned to beaa561337)