fish2018/pansou · warning

无法解析响应

Error message

无法解析响应

What it means

extractLoginInfo (plugin/qqpd/qqpd.go:1848) finds 'ptuiCB(' but the regex `ptuiCB\('0','0','([^']+)'` fails to capture a URL. This happens when the callback's status code is not '0' (login not fully successful) or the argument structure differs, so no URL group is matched. It is returned as '无法解析响应'.

Solutions

  1. Check the first ptuiCB argument in the response body to see the actual status code and handle it explicitly (expired, scanned-but-unconfirmed, etc.)
  2. Poll again until the user confirms on the phone, then re-run checkQRLoginStatus
  3. Loosen/extend the regex to capture any status and dispatch on it
  4. Regenerate the QR code if the code indicates expiration

Example fix

// before
re := regexp.MustCompile(`ptuiCB\('0','0','([^']+)'`)
matches := re.FindStringSubmatch(responseText)
if len(matches) < 2 {
    return "", "", fmt.Errorf("无法解析响应")
}
// after
re := regexp.MustCompile(`ptuiCB\('(\d+)','\d+','([^']*)'`)
m := re.FindStringSubmatch(responseText)
if m == nil {
    return "", "", fmt.Errorf("无法解析响应: %s", responseText)
}
if m[1] != "0" {
    return "", "", fmt.Errorf("登录未完成, 状态码: %s", m[1])
}
Defensive patterns

Strategy: type-guard

Validate before calling

// inspect the ptuiCB status code before attempting URL extraction
re := regexp.MustCompile(`ptuiCB\('(\d+)'`)
m := re.FindStringSubmatch(bodyStr)
if m == nil || m[1] != "0" {
    return fmt.Errorf("login not complete, ptuiCB code=%v", m)
}

Type guard

func ptuiCBSuccess(body string) bool {
    re := regexp.MustCompile(`ptuiCB\('0','0','[^']+'`)
    return re.MatchString(body)
}
// call extractLoginInfo only if ptuiCBSuccess(bodyStr)

Try / catch

ptsigx, uin, err := p.extractLoginInfo(bodyStr)
if err != nil {
    if err.Error() == "无法解析响应" {
        return nil, errors.New("QR code scanned but not confirmed or expired; poll again or refresh QR")
    }
    return nil, err
}

Prevention

When it happens

Trigger: checkQRLoginStatus -> extractLoginInfo: response contains ptuiCB( but the callback arguments don't match `('0','0','<url>')` — e.g. ptuiCB('67','0',...) meaning the QR was scanned but not confirmed, or the code indicates expiration.

Common situations: User scanned the QR but hasn't confirmed on the phone yet, the QR code expired (code 65/67 states), or QQ changed the callback argument order.

Related errors


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

Appendix: source

Thrown at plugin/qqpd/qqpd.go:1848

	// 等待扫码
	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]

	// 提取uin
	uinRe := regexp.MustCompile(`uin=(\d+)`)
	uinMatches := uinRe.FindStringSubmatch(url)
	if len(uinMatches) < 2 {
		return "", "", fmt.Errorf("未找到uin")
	}

View on GitHub (pinned to beaa561337)