fish2018/pansou · error
读取下载链接响应失败
Error message
读取下载链接响应失败: %w
What it means
Wrapped I/O error in cyg plugin's getDownloadLinks (plugin/cyg/cyg.go:252): reading the body of the download-link HTTP response failed after a 200 status was received (connection reset, timeout, truncated body, etc.). The request itself succeeded, so this indicates a transport-level failure while consuming the response, not a bad URL or non-200 status.
Solutions
- Simply retry the request; this is usually transient — the plugin already retries the request itself, so check why retries also fail.
- Check proxy/VPN interference and try a direct connection.
- Verify the server is not truncating responses due to load (curl the endpoint repeatedly).
- If persistent, wrap the read with an io.LimitReader and tolerate partial failures, or increase client robustness (keep-alives disabled).
Defensive patterns
Strategy: retry
Try / catch
var links []model.Link
var err error
for i := 0; i < 3; i++ {
links, err = p.getDownloadLinks(id)
if err == nil || !errors.Is(err, io.ErrUnexpectedEOF) {
break
}
time.Sleep(time.Duration(i+1) * time.Second)
} Prevention
- Retry once or twice automatically; truncated bodies are usually transient.
- Avoid long-lived proxied connections when fetching large JSON bodies.
- Keep the HTTP client's defaults sane (no aggressive idle-conn killing).
When it happens
Trigger: The server closes the connection prematurely while sending the download-links JSON body (unexpected EOF, connection reset by peer, chunked-encoding truncation).
Common situations: 远端服务器响应缓慢导致读取超时;代理/网络抖动中断长响应传输。
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/8a0a46f04744a406.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/cyg/cyg.go:252
// 设置请求头
p.setRequestHeaders(req)
// 发送请求
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return nil, fmt.Errorf("下载链接请求失败: %w", err)
}
defer resp.Body.Close()
// 检查状态码
if resp.StatusCode != 200 {
return nil, fmt.Errorf("下载链接请求状态码: %d", resp.StatusCode)
}
// 解析响应
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("读取下载链接响应失败: %w", err)
}
var downloadData []CygDownload
if err := json.Unmarshal(body, &downloadData); err != nil {
return nil, fmt.Errorf("下载链接JSON解析失败: %w", err)
}
// 转换为model.Link格式
return p.convertToLinks(downloadData), nil
}
// convertToSearchResult 转换为标准搜索结果格式
func (p *CygPlugin) convertToSearchResult(post CygPost, links []model.Link) model.SearchResult {
return model.SearchResult{
UniqueID: fmt.Sprintf("cyg-%d", post.ID),
Title: p.cleanHTML(post.Title.Rendered),
Content: p.cleanHTML(post.Excerpt.Rendered),
Datetime: p.parseDateTime(post.Date),View on GitHub (pinned to beaa561337)