fish2018/pansou · error
[ ] 解析JSON响应失败
Error message
[%s] 解析JSON响应失败: %w
What it means
searchImpl unmarshals the response body into WanouAPIResponse with encoding/json. If the body is not valid JSON or does not match the struct (e.g. an HTML error page or CAPTCHA page is returned), it throws '解析JSON响应失败' (failed to parse JSON response).
Solutions
- Log the first ~200 bytes of body to see what was actually returned
- Check for HTML: the mirror is likely serving an anti-bot/block page — change domain or add cookies
- Update WanouAPIResponse struct to match the current API schema
- Verify the endpoint URL still points at the JSON API
Example fix
// before
if err := json.Unmarshal(body, &apiResponse); err != nil {
return nil, fmt.Errorf("[%s] 解析JSON响应失败: %w", p.Name(), err)
}
// after
if err := json.Unmarshal(body, &apiResponse); err != nil {
log.Debugf("wanou non-JSON body: %.200s", body)
return nil, fmt.Errorf("[%s] 解析JSON响应失败(非JSON/反爬页面?): %w", p.Name(), err)
} Defensive patterns
Strategy: validation
Validate before calling
if !json.Valid(body) {
return fmt.Errorf("wanou returned non-JSON (likely block page): %.100s", body)
} Try / catch
var apiResponse WanouAPIResponse
if err := json.Unmarshal(body, &apiResponse); err != nil {
if !json.Valid(body) {
return nil, fmt.Errorf("upstream returned HTML/block page")
}
return nil, fmt.Errorf("schema mismatch: %w", err)
} Prevention
- Inspect raw bodies when the shape changes
- Keep the response struct in sync with the live API
- Handle compressed responses (Accept-Encoding)
- Detect and rotate away from block-page-serving mirrors
When it happens
Trigger: The wanou endpoint returns HTML (block page, Cloudflare challenge, login page), an empty body, or JSON with fields whose types don't match WanouAPIResponse (e.g. string "code" vs number).
Common situations: Anti-bot page returned with HTTP 200; the site's API changed its response shape; the domain now serves an HTML notice; response compressed/garbled due to missing Accept-Encoding handling.
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/1a9ebf0b084df51b.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/wanou/wanou.go:154
req.Header.Set("Referer", "https://woog.nxog.eu.org/")
req.Header.Set("Cache-Control", "no-cache")
// 发送请求
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return nil, fmt.Errorf("[%s] 搜索请求失败: %w", p.Name(), err)
}
defer resp.Body.Close()
// 解析JSON响应
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("[%s] 读取响应失败: %w", p.Name(), err)
}
var apiResponse WanouAPIResponse
if err := json.Unmarshal(body, &apiResponse); err != nil {
return nil, fmt.Errorf("[%s] 解析JSON响应失败: %w", p.Name(), err)
}
// 检查API响应状态
if apiResponse.Code != 1 {
return nil, fmt.Errorf("[%s] API返回错误: %s", p.Name(), apiResponse.Msg)
}
// 解析搜索结果
var results []model.SearchResult
for _, item := range apiResponse.List {
if result := p.parseAPIItem(item); result.Title != "" {
results = append(results, result)
}
}
return results, nil
}
View on GitHub (pinned to beaa561337)