fish2018/pansou · error
读取二维码失败
Error message
读取二维码失败: %w
What it means
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.
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.
Example fix
// before
client := &http.Client{} // no timeout
// after
client := &http.Client{Timeout: 15 * time.Second}
...
qrcodeBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, "", fmt.Errorf("读取二维码失败: %w", err) // retry caller-side
} Defensive patterns
Strategy: retry
Try / catch
qrcodeBytes, _, err := generateQRCodeWithSig(...)
if err != nil {
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
// increase timeout and retry once
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/1efcfeed8fd722ad.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/qqpd/qqpd.go:2092
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
resp, err := client.Get(qrcodeURL)
if err != nil {
return nil, "", fmt.Errorf("请求二维码失败: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return nil, "", fmt.Errorf("二维码请求返回状态码: %d", resp.StatusCode)
}
// 读取二维码图片
qrcodeBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, "", fmt.Errorf("读取二维码失败: %w", err)
}
// 提取qrsig(用于后续登录检测)
setCookie := resp.Header.Get("Set-Cookie")
qrsig := extractQrsig(setCookie)
if qrsig != "" && DebugLog {
fmt.Printf("[QQPD] 二维码生成成功,qrsig: %s\n", qrsig[:20]+"...")
}
return qrcodeBytes, qrsig, nil
}
// extractQrsig 从Set-Cookie中提取qrsig
func extractQrsig(setCookie string) string {
cookies := strings.Split(setCookie, ";")
for _, cookie := range cookies {
cookie = strings.TrimSpace(cookie)
if strings.HasPrefix(cookie, "qrsig=") {View on GitHub (pinned to beaa561337)