{"record":{"id":"c5538523f89ec0c3","repo":"fish2018/pansou","slug":"json-w-s","errorCode":null,"errorMessage":"JSON解析失败: %w, 响应内容: %s","messagePattern":"JSON解析失败: %w, 响应内容: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/gying/gying.go","lineNumber":2173,"sourceCode":"\t// 从POST登录响应中收集cookies\n\tcollectSetCookies(headers, cookieMap)\n\tlogSetCookiesForDebug(headers, \"[Gying]   POST登录Cookie: %s=%s\\n\", 20)\n\n\tif DebugLog {\n\t\tfmt.Printf(\"[Gying] 响应状态码: %d\\n\", statusCode)\n\t}\n\n\t// 读取响应\n\tif DebugLog {\n\t\tfmt.Printf(\"[Gying] 响应内容: %s\\n\", string(body))\n\t}\n\n\tvar loginResp map[string]interface{}\n\tif err := json.Unmarshal(body, &loginResp); err != nil {\n\t\tif DebugLog {\n\t\t\tfmt.Printf(\"[Gying] JSON解析失败: %v\\n\", err)\n\t\t}\n\t\treturn nil, \"\", fmt.Errorf(\"JSON解析失败: %w, 响应内容: %s\", err, string(body))\n\t}\n\n\tif DebugLog {\n\t\tfmt.Printf(\"[Gying] 解析后的响应: %+v\\n\", loginResp)\n\t\tfmt.Printf(\"[Gying] code字段类型: %T, 值: %v\\n\", loginResp[\"code\"], loginResp[\"code\"])\n\t}\n\n\t// 检查登录结果（兼容多种类型：int、float64、json.Number、string）\n\tvar codeValue int\n\tcodeInterface := loginResp[\"code\"]\n\n\tswitch v := codeInterface.(type) {\n\tcase int:\n\t\tcodeValue = v\n\tcase float64:\n\t\tcodeValue = int(v)\n\tcase int64:\n\t\tcodeValue = int(v)","sourceCodeStart":2155,"sourceCodeEnd":2191,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/gying/gying.go#L2155-L2191","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"res, err := gyingLogin(ctx, creds)\nif err != nil {\n    if strings.Contains(err.Error(), \"JSON解析失败\") {\n        // body wasn't JSON — inspect embedded 响应内容 for HTML/challenge page\n        log.Printf(\"non-JSON login response: %v\", err)\n        clearStoredCookies()\n        return fmt.Errorf(\"login endpoint returned non-JSON; cookies cleared, retry: %w\", err)\n    }\n    return err\n}","preventionTips":["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."],"tags":["json","parsing","login","unexpected-response"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}