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

  1. Log the first ~200 bytes of body to see what was actually returned
  2. Check for HTML: the mirror is likely serving an anti-bot/block page — change domain or add cookies
  3. Update WanouAPIResponse struct to match the current API schema
  4. 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

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)