{"record":{"id":"58a12630d0d13de2","repo":"fish2018/pansou","slug":"d-58a126","errorCode":null,"errorMessage":"二维码请求返回状态码: %d","messagePattern":"二维码请求返回状态码: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/qqpd/qqpd.go","lineNumber":2086,"sourceCode":"// generateQRCodeWithSig 生成QQ登录二维码并返回qrsig\nfunc (p *QQPDPlugin) generateQRCodeWithSig() ([]byte, string, error) {\n\tqrcodeURL := \"https://xui.ptlogin2.qq.com/ssl/ptqrshow?appid=1600001587&e=2&l=M&s=3&d=72&v=4&t=0.3680011491059967&daid=823&pt_3rd_aid=0\"\n\n\tclient := &http.Client{\n\t\tTimeout: 15 * time.Second,\n\t\tTransport: &http.Transport{\n\t\t\tTLSClientConfig: &tls.Config{InsecureSkipVerify: true},\n\t\t},\n\t}\n\n\tresp, err := client.Get(qrcodeURL)\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"请求二维码失败: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != 200 {\n\t\treturn nil, \"\", fmt.Errorf(\"二维码请求返回状态码: %d\", resp.StatusCode)\n\t}\n\n\t// 读取二维码图片\n\tqrcodeBytes, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"读取二维码失败: %w\", err)\n\t}\n\n\t// 提取qrsig（用于后续登录检测）\n\tsetCookie := resp.Header.Get(\"Set-Cookie\")\n\tqrsig := extractQrsig(setCookie)\n\tif qrsig != \"\" && DebugLog {\n\t\tfmt.Printf(\"[QQPD] 二维码生成成功，qrsig: %s\\n\", qrsig[:20]+\"...\")\n\t}\n\n\treturn qrcodeBytes, qrsig, nil\n}\n","sourceCodeStart":2068,"sourceCodeEnd":2104,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/qqpd/qqpd.go#L2068-L2104","documentation":"generateQRCodeWithSig in plugin/qqpd checks the HTTP status of the QR-code image endpoint and rejects any non-200 response with the actual status code embedded. It is a guard against serving corrupted/absent QR images to the login flow; callers handleGetStatus and handleRefreshQRCode will surface this to the user as a QR-code fetch failure.","triggerScenarios":"The GET request to the QQ PD QR-code endpoint returns a status code other than 200 (e.g. 403 anti-bot block, 429 rate limit, 502/503 upstream outage).","commonSituations":"Server-side rate limiting after repeated QR refreshes; the QQ endpoint changing or blocking datacenter IPs; transient upstream errors during QR refresh loops.","solutions":["Check the embedded status code: 403/429 means the client IP is blocked or rate-limited — wait and retry, or use a proxy/rotating exit IP.","Retry generateQRCodeWithSig (via handleRefreshQRCode) after a short backoff for transient 5xx codes.","Verify the QR-code endpoint URL and that required headers/cookies are still valid (endpoint may have changed server-side).","Update the plugin if the upstream API contract changed."],"exampleFix":"// before\nresp, err := client.Get(qrURL)\n...\n// after — retry on transient statuses\nfor attempt := 0; attempt < 3; attempt++ {\n    resp, err := client.Get(qrURL)\n    if err == nil {\n        if resp.StatusCode == 200 {\n            break\n        }\n        resp.Body.Close()\n    }\n    time.Sleep(time.Duration(attempt+1) * time.Second)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"results, err := generateQRCodeWithSig(...)\nif err != nil {\n    if strings.Contains(err.Error(), \"状态码: 429\") || strings.Contains(err.Error(), \"状态码: 403\") {\n        time.Sleep(2 * time.Second)\n        // retry once, else surface to user as \"QR fetch blocked, try later\"\n    }\n}","preventionTips":["Space out QR refreshes to avoid rate limiting","Retry only on transient 5xx/429, fail fast on 4xx","Monitor the endpoint's availability from your deployment network"],"tags":["network","http","qrcode","login"],"backgroundTag":"http-non-200-response","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"}