fish2018/pansou · error

请求二维码失败

Error message

请求二维码失败: %w

What it means

generateQRCodeWithSig (plugin/qqpd/qqpd.go:2081) performs client.Get(qrcodeURL) to download the QR code image; any transport failure is wrapped as '请求二维码失败: %w'. Called from handleGetStatus and handleRefreshQRCode, this error means the QR image could not be fetched from QQ's qrcode endpoint over an http.Client configured with InsecureSkipVerify TLS.

Solutions

  1. Check the wrapped cause to identify DNS vs timeout vs connection refused
  2. Verify outbound connectivity: curl -v the qrcode URL from the deployment host
  3. Add or honor proxy configuration if the environment requires one
  4. Implement a retry with backoff for transient network failures when generating the QR code

Example fix

// before
resp, err := client.Get(qrcodeURL)
if err != nil {
    return nil, "", fmt.Errorf("请求二维码失败: %w", err)
}
// after
var resp *http.Response
for attempt := 0; attempt < 3; attempt++ {
    resp, err = client.Get(qrcodeURL)
    if err == nil {
        break
    }
    time.Sleep(time.Duration(attempt+1) * 200 * time.Millisecond)
}
if err != nil {
    return nil, "", fmt.Errorf("请求二维码失败: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

// probe reachability before generating the QR code
conn, err := net.DialTimeout("tcp", "ssl.ptlogin2.qq.com:443", 3*time.Second)
if err != nil {
    return fmt.Errorf("cannot reach QQ qrcode host: %w", err)
}
conn.Close()

Try / catch

img, _, err := p.generateQRCodeWithSig(sig)
if err != nil {
    var netErr net.Error
    if errors.As(err, &netErr) && netErr.Timeout() {
        // transient; retry QR generation after backoff
    }
    return err
}

Prevention

When it happens

Trigger: handleGetStatus or handleRefreshQRCode triggers QR generation; client.Get fails with a DNS error, connection refused/timeout, TLS handshake failure, or proxy error before a response is received.

Common situations: Host has no outbound internet access or DNS failure, a corporate proxy blocking ssl.ptlogin2.qq.com, transient network flaps, or firewall egress rules in containerized deployments.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/9a09ada0c32259ad. Report an issue: GitHub.

Appendix: source

Thrown at plugin/qqpd/qqpd.go:2081

		return uin[:4] + "****" + uin[len(uin)-2:]
	}
	return uin[:2] + "****" + uin[len(uin)-2:]
}

// generateQRCodeWithSig 生成QQ登录二维码并返回qrsig
func (p *QQPDPlugin) generateQRCodeWithSig() ([]byte, string, error) {
	qrcodeURL := "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"

	client := &http.Client{
		Timeout: 15 * time.Second,
		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]+"...")

View on GitHub (pinned to beaa561337)