{"record":{"id":"1efcfeed8fd722ad","repo":"fish2018/pansou","slug":"w-1efcfe","errorCode":null,"errorMessage":"读取二维码失败: %w","messagePattern":"读取二维码失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/qqpd/qqpd.go","lineNumber":2092,"sourceCode":"\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\n// extractQrsig 从Set-Cookie中提取qrsig\nfunc extractQrsig(setCookie string) string {\n\tcookies := strings.Split(setCookie, \";\")\n\tfor _, cookie := range cookies {\n\t\tcookie = strings.TrimSpace(cookie)\n\t\tif strings.HasPrefix(cookie, \"qrsig=\") {","sourceCodeStart":2074,"sourceCodeEnd":2110,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/qqpd/qqpd.go#L2074-L2110","documentation":"After a successful 200 response, generateQRCodeWithSig reads the QR-code image body with ioutil.ReadAll; if the read fails (connection reset mid-body, timeout, truncated response), it wraps the io error as \"读取二维码失败\". The QR image bytes cannot be obtained, so login state rendering must abort.","triggerScenarios":"ioutil.ReadAll(resp.Body) returns an error after the QR endpoint returned 200 — e.g. connection reset by peer, context deadline exceeded, or proxy dropping the stream mid-transfer.","commonSituations":"Unstable network or proxy between client and the QQ QR endpoint; server closes connection early under load; HTTP client timeout shorter than the image transfer needs.","solutions":["Retry the QR-code request; transient body-read errors usually succeed on a second attempt.","Increase the HTTP client timeout (http.Client{Timeout: ...}) if large latencies cause the read to expire.","Check proxy/firewall stability if behind a corporate or residential proxy.","Check the wrapped %w error for the root cause (reset, EOF, timeout) and address that specifically."],"exampleFix":"// before\nclient := &http.Client{} // no timeout\n// after\nclient := &http.Client{Timeout: 15 * time.Second}\n...\nqrcodeBytes, err := io.ReadAll(resp.Body)\nif err != nil {\n    return nil, \"\", fmt.Errorf(\"读取二维码失败: %w\", err) // retry caller-side\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"qrcodeBytes, _, err := generateQRCodeWithSig(...)\nif err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() {\n        // increase timeout and retry once\n    }\n}","preventionTips":["Configure a generous http.Client timeout for image downloads","Prefer stable, low-latency network paths; avoid flaky proxies","Retry body reads once on transient io errors before surfacing to the user"],"tags":["network","io","qrcode","login"],"backgroundTag":"file-read-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"}