fix(weixin): 空token''连接''不再阻塞+409请先扫码登录;Connect空token返回ErrNeedsLogin
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

面板点''连接''此前触发阻塞式扫码(最长8min)不展示二维码→挂起。修:
- weixin adapter Connect: 空token返回 ErrNeedsLogin(非阻塞), 扫码走独立 login-qr/login-status
- adminChannelOpen: errors.Is(ErrNeedsLogin)→409'该渠道尚未登录:请先扫码登录再连接'(不再500/挂起)
- login_test.go 改用 StartLogin/LoginStatus 驱动(与旧Connect阻塞行为解耦)
build/vet/test 全绿, 已部署.
This commit is contained in:
Aska committed 2026-09-07 21:06:10 +08:00
1 parent abb137cfe2
commit 3f2c981cf8
3 files changed
+70 -81

No files matched your search

+8 -3
View File
@@ -75,6 +75,9 @@ var (
ErrLoginTimeout = errors.New("weixin_ilink: qr login timed out")
// ErrSessionExpired is returned when iLink reports errcode=-14.
ErrSessionExpired = errors.New("weixin_ilink: session expired, re-scan required")
// ErrNeedsLogin is returned by Connect when no bot_token is configured yet; the
// scan-code bind must be driven via the panel login-qr/login-status endpoints.
ErrNeedsLogin = errors.New("weixin_ilink: bot not logged in yet, scan the QR")
// ErrNoContextToken is returned when a send lacks the peer's context_token.
ErrNoContextToken = errors.New("weixin_ilink: no context_token for peer")
// ErrProactiveWindow is returned when a proactive push is outside 24h.
@@ -234,9 +237,11 @@ func (a *Adapter) Connect(ctx context.Context) error {
return nil
}
if token == "" {
if err := a.login(ctx); err != nil {
return fmt.Errorf("weixin_ilink: connect: %w", err)
}
// No token yet: the scan-code bind must be driven out-of-band (the panel's
// login-qr / login-status endpoints, design/08 §4). Never block a "connect"
// HTTP call on the waiting QR — surface ErrNeedsLogin so the caller tells the
// owner to scan, rather than holding the request for up to the login timeout.
return ErrNeedsLogin
}
a.mu.Lock()
a.connected = true