fish2018/pansou · error

未找到ptuiCB

Error message

未找到ptuiCB

What it means

extractLoginInfo (plugin/qqpd/qqpd.go:1841) expects the ptqrlogin response to contain a JavaScript callback starting with 'ptuiCB('. If strings.Index cannot find it, it returns '未找到ptuiCB'. This means the response body is not the expected QQ login callback format at all.

Solutions

  1. Print and inspect the raw response body stored in the preceding log line
  2. Confirm the response is really a success payload; check ptuiCB's first argument code (0 = success)
  3. Update extractLoginInfo's parsing if QQ changed the callback format
  4. Regenerate the QR code and retry, as stale sessions can yield malformed payloads

Example fix

// before
start := strings.Index(responseText, "ptuiCB(")
if start == -1 {
    return "", "", fmt.Errorf("未找到ptuiCB")
}
// after
start := strings.Index(responseText, "ptuiCB(")
if start == -1 {
    return "", "", fmt.Errorf("未找到ptuiCB, 响应前缀: %.200s", responseText)
}
Defensive patterns

Strategy: validation

Validate before calling

// pre-check before invoking the parser
if !strings.Contains(bodyStr, "ptuiCB(") {
    return errors.New("login response missing ptuiCB callback")
}

Try / catch

ptsigx, uin, err := p.extractLoginInfo(bodyStr)
if err != nil {
    if err.Error() == "未找到ptuiCB" {
        // unexpected body: save bodyStr to disk for diagnosis
        _ = os.WriteFile("last_qqpd_body.txt", []byte(bodyStr), 0644)
    }
    return err
}

Prevention

When it happens

Trigger: checkQRLoginStatus detects '登录成功' in bodyStr and calls extractLoginInfo, but the body lacks any 'ptuiCB(' substring — e.g. an unexpected HTML/JSON error page.

Common situations: QQ server returning an error or captcha page instead of the callback, an encoding issue mangling the body, or a QQ-side format change renaming/restructuring ptuiCB.

Related errors


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

Appendix: source

Thrown at plugin/qqpd/qqpd.go:1841

		return &LoginResult{
			Status:   "success",
			Cookie:   cookie,
			QQMasked: qqMasked,
		}, nil
	}

	// 等待扫码
	return &LoginResult{Status: "waiting"}, nil
}

// extractLoginInfo 从登录响应中提取ptsigx和uin
func (p *QQPDPlugin) extractLoginInfo(responseText string) (string, string, error) {
	// 解析返回的JavaScript回调:ptuiCB('0','0','url',...)
	// 需要提取第3个参数的URL
	start := strings.Index(responseText, "ptuiCB(")
	if start == -1 {
		return "", "", fmt.Errorf("未找到ptuiCB")
	}

	// 简单解析,提取URL部分
	re := regexp.MustCompile(`ptuiCB\('0','0','([^']+)'`)
	matches := re.FindStringSubmatch(responseText)
	if len(matches) < 2 {
		return "", "", fmt.Errorf("无法解析响应")
	}

	url := matches[1]

	// 提取ptsigx
	ptsigxRe := regexp.MustCompile(`ptsigx=([A-Za-z0-9]+)`)
	ptsigxMatches := ptsigxRe.FindStringSubmatch(url)
	if len(ptsigxMatches) < 2 {
		return "", "", fmt.Errorf("未找到ptsigx")
	}
	ptsigx := ptsigxMatches[1]

View on GitHub (pinned to beaa561337)