fish2018/pansou · error
JSON解析失败: , 响应内容
Error message
JSON解析失败: %w, 响应内容: %s
What it means
After the login POST returns, gying expects the response body to be JSON and unmarshals it into map[string]interface{}. If the body is not valid JSON (HTML error page, empty body, Cloudflare interstitial), json.Unmarshal fails and the plugin returns 'JSON解析失败: %w, 响应内容: %s', embedding the raw body for diagnosis.
Solutions
- Read the 响应内容 embedded in the error — it shows exactly what came back (HTML? empty? truncated?).
- Confirm the login endpoint URL is current; the site may have moved its API and now returns an HTML page.
- Clear cookies and retry — a Cloudflare interstitial returning 200 with HTML is the usual culprit.
- Check whether the site is under maintenance and serving an HTML notice with status 200.
- Update the plugin if the site changed its login response contract.
Defensive patterns
Strategy: try-catch
Try / catch
res, err := gyingLogin(ctx, creds)
if err != nil {
if strings.Contains(err.Error(), "JSON解析失败") {
// body wasn't JSON — inspect embedded 响应内容 for HTML/challenge page
log.Printf("non-JSON login response: %v", err)
clearStoredCookies()
return fmt.Errorf("login endpoint returned non-JSON; cookies cleared, retry: %w", err)
}
return err
} Prevention
- Clear cookies when you see HTML instead of JSON — usually a challenge page.
- Verify the login endpoint URL after site updates.
- Log raw bodies (the error already embeds them) before changing code.
- Detect maintenance windows before running login jobs.
When it happens
Trigger: Login step 2 receives a 200 response whose body is not JSON — an HTML login page (wrong endpoint/redirect), an empty body, truncated response, or a challenge page that still returned HTTP 200.
Common situations: Site changed its login API or returns HTML on soft failures; request hit a redirect target that serves HTML; response gzip/encoding mishandled; server returned an error page with status 200.
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/c5538523f89ec0c3.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/gying/gying.go:2173
// 从POST登录响应中收集cookies
collectSetCookies(headers, cookieMap)
logSetCookiesForDebug(headers, "[Gying] POST登录Cookie: %s=%s\n", 20)
if DebugLog {
fmt.Printf("[Gying] 响应状态码: %d\n", statusCode)
}
// 读取响应
if DebugLog {
fmt.Printf("[Gying] 响应内容: %s\n", string(body))
}
var loginResp map[string]interface{}
if err := json.Unmarshal(body, &loginResp); err != nil {
if DebugLog {
fmt.Printf("[Gying] JSON解析失败: %v\n", err)
}
return nil, "", fmt.Errorf("JSON解析失败: %w, 响应内容: %s", err, string(body))
}
if DebugLog {
fmt.Printf("[Gying] 解析后的响应: %+v\n", loginResp)
fmt.Printf("[Gying] code字段类型: %T, 值: %v\n", loginResp["code"], loginResp["code"])
}
// 检查登录结果(兼容多种类型:int、float64、json.Number、string)
var codeValue int
codeInterface := loginResp["code"]
switch v := codeInterface.(type) {
case int:
codeValue = v
case float64:
codeValue = int(v)
case int64:
codeValue = int(v)View on GitHub (pinned to beaa561337)