refactor(weixin-ilink): 措辞纠正 —「会话过期」→「会话被 iLink 拒绝」(零逻辑改动)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

事实(主人 2026-10-03 确认):iLink 的 bot token 是长期凭据(一个月前扫码的仍可用);errcode=-14 是 iLink 侧拒绝/作废该会话,不是时间性过期;且至今未观测到真实 -14(当日全部日志 0 次)。此前代码把这些写成「过期」,属沿用的旧命名,现纠正。
- 纯改名/文案:ErrSessionExpired→ErrSessionRejected、errSessionExpired→errcodeSessionRejected、expired/expiredToken→rejected/rejectedToken、markExpired/expiredLocked/expiredState→markRejected/rejectedLocked/rejectedState;409 错误码 session_expired→session_rejected
- 行为一字未改:显式标记 / Connect 不假 OK / 面板 needsRescan+lastError / 扫码或换新 token 即清除 全部保留
- 微信协议自身的「二维码过期」与 auth 的 JWT/refresh 过期一律未动(那些是真·时间性过期)
- Docs/api-client v0.39 补事实说明;顺手收尾 3 处残留注释(admin.go / channelbridge/inbound.go / readloop_test.go)
This commit is contained in:
AskaEth committed 2026-10-03 18:26:27 +08:00
1 parent cdc370dc82
commit a51aadeef4
14 files changed
+205 -192

No files matched your search

+10 -10
View File
@@ -119,11 +119,11 @@ func (a *Adapter) StartLogin(ctx context.Context) (LoginQR, error) {
a.loginMu.Lock()
defer a.loginMu.Unlock()
// Already bound → scanning is moot — unless the stored token is EXPIRED: iLink
// rejected it with errcode=-14, so it is not a usable bind and the owner must
// be able to re-scan (otherwise the only way out of the expired state would be
// Already bound → scanning is moot — unless iLink REJECTED the stored token
// (errcode=-14), so it is not a usable bind and the owner must be able to
// re-scan (otherwise the only way out of the rejected state would be
// unreachable). A live token still short-circuits the QR flow as before.
if expired, _ := a.expiredState(); a.hasToken() && !expired {
if rejected, _ := a.rejectedState(); a.hasToken() && !rejected {
return LoginQR{}, ErrAlreadyLoggedIn
}
if sess := a.loginSession; sess != nil {
@@ -181,19 +181,19 @@ func (a *Adapter) StartLogin(ctx context.Context) (LoginQR, error) {
// LoginStatus reports the current scan-login state. A non-empty bot token
// overrides to "confirmed" even if a stale session is still recorded, so the panel
// always sees the true binding — except when that token is EXPIRED: iLink rejected
// it with errcode=-14, so reporting "confirmed" would make the panel re-persist a
// dead credential and call the bind a success. An expired bind is reported as
// failed with the re-scan reason instead, while a re-scan already in progress
// always sees the true binding — except when iLink REJECTED that token
// (errcode=-14), so reporting "confirmed" would make the panel re-persist a dead
// credential and call the bind a success. A rejected bind is reported as failed
// with the re-scan reason instead, while a re-scan already in progress
// keeps its own state. detail provides the bot id on confirmation and the failure
// reason on failure.
func (a *Adapter) LoginStatus(ctx context.Context) (status, detail string) {
a.mu.Lock()
defer a.mu.Unlock()
if a.expiredLocked() {
if a.rejectedLocked() {
if a.loginStatus == LoginStatusWaiting || a.loginStatus == LoginStatusNeedVerifyCode {
// A re-scan the owner already started: report its progress, not the
// expired state it is meant to replace.
// rejected state it is meant to replace.
return a.loginStatus, a.loginDetail
}
return LoginStatusFailed, a.rescanDetail