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

  1. Read the 响应内容 embedded in the error — it shows exactly what came back (HTML? empty? truncated?).
  2. Confirm the login endpoint URL is current; the site may have moved its API and now returns an HTML page.
  3. Clear cookies and retry — a Cloudflare interstitial returning 200 with HTML is the usual culprit.
  4. Check whether the site is under maintenance and serving an HTML notice with status 200.
  5. 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

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)