fish2018/pansou · error
下载链接JSON解析失败
Error message
下载链接JSON解析失败: %w
What it means
getDownloadLinks fails to json.Unmarshal the response body into []CygDownload and wraps the error with "下载链接JSON解析失败". It means the server replied 200 but the body is not the expected JSON array of download objects.
Solutions
- Dump the raw body (on unmarshal failure) to see what was actually returned.
- Compare the response against the CygDownload struct and update its json field tags after a site schema change.
- Check whether the endpoint now returns an object wrapper instead of a bare array and adjust the target type.
- Verify Content-Type is application/json; if HTML, treat it as an anti-bot/upstream error rather than a parse bug.
Example fix
// before
var downloadData []CygDownload
if err := json.Unmarshal(body, &downloadData); err != nil {
return nil, fmt.Errorf("下载链接JSON解析失败: %w", err)
}
// after
var downloadData []CygDownload
if err := json.Unmarshal(body, &downloadData); err != nil {
return nil, fmt.Errorf("下载链接JSON解析失败: %w, body: %.200s", err, body)
} Defensive patterns
Strategy: validation
Validate before calling
ct := resp.Header.Get("Content-Type")
if !strings.Contains(ct, "json") {
return fmt.Errorf("expected JSON, got %s", ct)
} Try / catch
links, err := p.getDownloadLinks(id)
if err != nil && strings.Contains(err.Error(), "JSON解析失败") {
// response was not the expected schema; treat source as changed/broken
return nil, fmt.Errorf("source schema changed, plugin update needed: %w", err)
} Prevention
- Check Content-Type before assuming JSON.
- Pin/verify the expected response shape after site updates.
- Log a truncated body on unmarshal failure to speed up diagnosis.
When it happens
Trigger: The 200 response body is HTML (error page / anti-bot challenge), empty, or its JSON schema changed so it no longer unmarshals into []CygDownload.
Common situations: Site deployed a new version changing the download API response shape, WAF serving an HTML challenge with status 200, empty body due to upstream cache miss, or CDN returning a compressed body the client did not request.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/b448a4db2b569b1a.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/cyg/cyg.go:257
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),
Tags: []string{post.CategoryName},
Links: links,
Channel: "", // 插件搜索结果必须为空字符串
}
}View on GitHub (pinned to beaa561337)