{"record":{"id":"c1ab290bb1d4b584","repo":"fish2018/pansou","slug":"cookie-w-c1ab29","errorCode":null,"errorMessage":"获取Cookie失败: %w","messagePattern":"获取Cookie失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/qqpd/qqpd.go","lineNumber":1808,"sourceCode":"\t\treturn &LoginResult{Status: \"expired\"}, nil\n\t}\n\n\tif strings.Contains(bodyStr, \"登录成功\") {\n\t\t// 提取ptsigx和uin\n\t\tptsigx, uin, err := p.extractLoginInfo(bodyStr)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"[QQPD] 提取登录信息失败: %v, 响应: %s\\n\", err, bodyStr)\n\t\t\treturn nil, fmt.Errorf(\"提取登录信息失败: %w\", err)\n\t\t}\n\n\t\t// 获取完整Cookie（传递ptqrlogin返回的所有Set-Cookie）\n\t\tallSetCookies := resp.Header.Values(\"Set-Cookie\")\n\t\tsetCookieStr := strings.Join(allSetCookies, \"; \")\n\n\t\tcookie, err := p.fetchFullCookie(uin, ptsigx, setCookieStr)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"[QQPD] 获取Cookie失败: %v\\n\", err)\n\t\t\treturn nil, fmt.Errorf(\"获取Cookie失败: %w\", err)\n\t\t}\n\n\t\t// 生成脱敏QQ号\n\t\tqqMasked := p.maskQQ(uin)\n\n\t\tif DebugLog {\n\t\t\tfmt.Printf(\"[QQPD] 登录成功！QQ: %s, Cookie长度: %d, 包含keys: \", qqMasked, len(cookie))\n\t\t\tcookies := parseCookieString(cookie)\n\t\t\tkeys := make([]string, 0, len(cookies))\n\t\t\tfor k := range cookies {\n\t\t\t\tkeys = append(keys, k)\n\t\t\t}\n\t\t\tfmt.Printf(\"%v\\n\", keys)\n\t\t}\n\n\t\treturn &LoginResult{\n\t\t\tStatus:   \"success\",\n\t\t\tCookie:   cookie,","sourceCodeStart":1790,"sourceCodeEnd":1826,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/qqpd/qqpd.go#L1790-L1826","documentation":"checkQRLoginStatus (plugin/qqpd/qqpd.go:1808) wraps failures from p.fetchFullCookie(uin, ptsigx, setCookieStr) as '获取Cookie失败: %w'. After QR login succeeds and ptsigx/uin are extracted, the plugin exchanges them at QQ's check_sig endpoint for the full cookie set; any network error or non-success status there surfaces as this error.","triggerScenarios":"handleCheckLogin -> checkQRLoginStatus: the ptqrlogin response succeeded and ptsigx/uin were parsed, but the follow-up fetchFullCookie HTTP request fails (transport error, non-2xx, or missing expected cookies in the response).","commonSituations":"ptsigx expired because the check_sig request happened too late, QQ rate-limiting or blocking the client IP, network outage, or QQ changing the check_sig response shape so the plugin can't assemble the cookie.","solutions":["Check the underlying error printed by the [QQPD] log line to distinguish network vs parsing failure","Retry the check_login poll promptly after QR scan — ptsigx is short-lived","Verify outbound connectivity to QQ's check_sig domain (ssl.ptlogin2.qq.com)","Re-issue a fresh QR code if the sign exchange keeps failing"],"exampleFix":"// before\ncookie, err := p.fetchFullCookie(uin, ptsigx, setCookieStr)\nif err != nil {\n    return nil, fmt.Errorf(\"获取Cookie失败: %w\", err)\n}\n// after\ncookie, err := p.fetchFullCookie(uin, ptsigx, setCookieStr)\nif err != nil {\n    return nil, fmt.Errorf(\"获取Cookie失败 (uin=%s): %w\", p.maskQQ(uin), err)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"user, err := p.checkQRLoginStatus(qrsig)\nif err != nil {\n    if strings.Contains(err.Error(), \"获取Cookie失败\") {\n        // ptsigx likely expired or check_sig request failed; restart QR flow\n        return p.restartQRFlow()\n    }\n    return err\n}","preventionTips":["Call check_login immediately after the user scans to avoid ptsigx expiry","Ensure stable connectivity to ssl.ptlogin2.qq.com","Apply the same cookie jar across ptqrlogin and check_sig requests","Add a fallback that re-issues a QR code after N cookie-exchange failures"],"tags":["http","qq-login","cookies"],"backgroundTag":"api-request-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"}