refactor(weixin-ilink): 措辞纠正 —「会话过期」→「会话被 iLink 拒绝」(零逻辑改动)
事实(主人 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:
1 parent
cdc370dc82
commit
a51aadeef4
14 files changed
+205
-192
No files matched your search
@@ -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
|
||||
|
||||
Reference in new issue
Block a user