{"record":{"id":"0f803c9dde93cf23","repo":"fish2018/pansou","slug":"w-0f803c","errorCode":null,"errorMessage":"提取登录信息失败: %w","messagePattern":"提取登录信息失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/qqpd/qqpd.go","lineNumber":1798,"sourceCode":"\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, _ := ioutil.ReadAll(resp.Body)\n\tbodyStr := string(body)\n\n\t// 检查登录状态\n\tif strings.Contains(bodyStr, \"二维码已失效\") {\n\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)","sourceCodeStart":1780,"sourceCodeEnd":1816,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/qqpd/qqpd.go#L1780-L1816","documentation":"In checkQRLoginStatus (plugin/qqpd/qqpd.go:1798), when the QR-login response contains '登录成功', the plugin calls extractLoginInfo to pull ptsigx and uin from the ptuiCB callback. If that parsing fails, the error is wrapped as '提取登录信息失败: %w'. It means QQ's login response was reported successful but its body did not match the expected ptuiCB format.","triggerScenarios":"handleCheckLogin polls checkQRLoginStatus; the response body contains '登录成功' but extractLoginInfo fails to find ptuiCB(...), the URL, ptsigx, or uin in it.","commonSituations":"QQ changed the ptqrlogin response format, a login confirmation step is pending so the URL lacks the expected query parameters, or an HTML error/captcha page is returned despite the success marker.","solutions":["Log the full response body (the plugin already prints it) and check whether the ptuiCB format changed","Update the regexes in extractLoginInfo to match the current QQ response format","Re-generate the QR code and retry the login — a stale/expired QR can yield malformed responses","Check for a pending confirmation state (user must confirm on the phone) before parsing"],"exampleFix":"// before\nreturn nil, fmt.Errorf(\"提取登录信息失败: %w\", err)\n// after\nreturn nil, fmt.Errorf(\"提取登录信息失败 (响应: %.200s): %w\", bodyStr, err)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"user, err := p.checkQRLoginStatus(qrsig)\nif err != nil {\n    if strings.Contains(err.Error(), \"提取登录信息失败\") {\n        // log the raw response and fall back to re-issuing the QR code\n    }\n    return err\n}","preventionTips":["Log raw ptqrlogin responses to detect QQ format changes early","Regenerate QR codes promptly instead of polling expired sessions","Require phone-side confirmation to complete before parsing the response","Pin/monitor the login flow so format changes are caught in staging"],"tags":["parsing","qq-login","qr-code"],"backgroundTag":"unexpected-response-shape","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"}