fish2018/pansou · warning
[ ] 搜索响应超过 字节
Error message
[%s] 搜索响应超过 %d 字节
What it means
Returned by searchImpl when the response body exceeds maxResponseSize (3 MiB, 3 << 20 bytes). The body is read through a LimitReader of maxResponseSize+1 bytes; if more than maxResponseSize bytes were actually read, the plugin rejects the response instead of processing an unexpectedly huge page. This is a defensive guard against the upstream site returning garbage, error pages with huge payloads, or being redirected to a different site.
Solutions
- Verify the effective final URL (resp.Request.URL) — a redirect to an unexpected domain indicates baseURL/domain takeover; update baseURL
- Check what the site actually returns with curl to confirm the page legitimately grew
- Raise maxResponseSize deliberately if the upstream page size grew
- Keep the guard but alert on it, since it usually signals a changed or hijacked upstream
Example fix
// before
body, err := io.ReadAll(io.LimitReader(resp.Body, maxResponseSize+1))
// after
body, err := io.ReadAll(io.LimitReader(resp.Body, maxResponseSize+1))
if len(body) > maxResponseSize {
return nil, fmt.Errorf("[%s] 搜索响应超过 %d 字节 (final URL: %s)", p.Name(), maxResponseSize, resp.Request.URL)
} Defensive patterns
Strategy: fallback
Validate before calling
// cannot be pre-validated; size only known after reading
Try / catch
if strings.Contains(err.Error(), "搜索响应超过") {
// treat as upstream anomaly: log resp.Request.URL and skip this source,
// don't crash the whole search
} Prevention
- Log the final redirected URL when this fires — often domain takeover
- Alert rather than raise maxResponseSize blindly
- Periodically curl the search endpoint to track normal page sizes
- Verify configured baseURL points at the legitimate domain
When it happens
Trigger: len(body) > maxResponseSize after reading: the site returns an unusually large page, a redirect to unrelated content (parked domain, ad interstitial), or an HTML error page bloated with scripts.
Common situations: The haitunsou domain expires or is taken over and the plugin is silently redirected to an unrelated large page; upstream begins embedding much more data in pages; misconfigured baseURL points at a mirror returning huge pages.
Understand the failure class
Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/2f18b522829af2a2.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/haitunsou/haitunsou.go:108
if err != nil {
return nil, fmt.Errorf("[%s] 创建搜索请求失败: %w", p.Name(), err)
}
setRequestHeaders(req, p.baseURL)
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("[%s] 搜索请求返回 HTTP %d", p.Name(), resp.StatusCode)
}
body, err := io.ReadAll(io.LimitReader(resp.Body, maxResponseSize+1))
if err != nil {
return nil, fmt.Errorf("[%s] 读取搜索响应失败: %w", p.Name(), err)
}
if len(body) > maxResponseSize {
return nil, fmt.Errorf("[%s] 搜索响应超过 %d 字节", p.Name(), maxResponseSize)
}
items, err := parseEmbeddedList(body)
if err != nil {
return nil, fmt.Errorf("[%s] 解析搜索结果失败: %w", p.Name(), err)
}
results := make([]model.SearchResult, 0, len(items))
seen := make(map[string]struct{}, len(items))
for _, item := range items {
result, ok := convertItem(item)
if !ok {
continue
}
key := result.Links[0].URL + "\x00" + result.Links[0].Password
if _, exists := seen[key]; exists {
continue
}
seen[key] = struct{}{}View on GitHub (pinned to beaa561337)