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
@@ -73,13 +73,12 @@ func (a *Adapter) SendProactive(ctx context.Context, msg adapter.UnifiedMessage)
|
||||
return a.sendToOne(ctx, peer, msg)
|
||||
}
|
||||
|
||||
// sendGuard reports the error a send must surface before touching the network: an
|
||||
// expired session (iLink already refused this token with errcode=-14) reads as
|
||||
// ErrSessionExpired — the owner must re-scan — while any other down session stays
|
||||
// ErrNotConnected.
|
||||
// sendGuard reports the error a send must surface before touching the network: a
|
||||
// session iLink already rejected (errcode=-14) reads as ErrSessionRejected — the
|
||||
// owner must re-scan — while any other down session stays ErrNotConnected.
|
||||
func (a *Adapter) sendGuard() error {
|
||||
if expired, reason := a.expiredState(); expired {
|
||||
return fmt.Errorf("weixin_ilink: send: %w: %s", ErrSessionExpired, reason)
|
||||
if rejected, reason := a.rejectedState(); rejected {
|
||||
return fmt.Errorf("weixin_ilink: send: %w: %s", ErrSessionRejected, reason)
|
||||
}
|
||||
if !a.IsConnected() {
|
||||
return adapter.ErrNotConnected
|
||||
@@ -165,12 +164,12 @@ func (a *Adapter) sendNative(ctx context.Context, peer, ctxToken string, items [
|
||||
bytes.NewReader(body), &out); err != nil {
|
||||
return fmt.Errorf("weixin_ilink: sendmessage: %w", err)
|
||||
}
|
||||
if out.Errcode == errSessionExpired {
|
||||
// The send path sees the same dead token as the poll path: record the
|
||||
// expired state so the adapter stops claiming a live session and the panel
|
||||
// can ask for a re-scan.
|
||||
a.markExpired(rescanReasonSendMessage)
|
||||
return ErrSessionExpired
|
||||
if out.Errcode == errcodeSessionRejected {
|
||||
// The send path sees the same rejected credential as the poll path: record
|
||||
// the rejected state so the adapter stops claiming a live session and the
|
||||
// panel can ask for a re-scan.
|
||||
a.markRejected(rescanReasonSendMessage)
|
||||
return ErrSessionRejected
|
||||
}
|
||||
if out.Ret != 0 {
|
||||
return fmt.Errorf("weixin_ilink: sendmessage ret=%d", out.Ret)
|
||||
@@ -190,11 +189,11 @@ func (a *Adapter) getUploadURL(ctx context.Context) (string, error) {
|
||||
bytes.NewReader(body), &raw); err != nil {
|
||||
return "", fmt.Errorf("weixin_ilink: getuploadurl: %w", err)
|
||||
}
|
||||
if intOf(raw["errcode"]) == errSessionExpired {
|
||||
// Media upload is part of the send path, so the same dead token is recorded
|
||||
// here too rather than degrading into "no url returned".
|
||||
a.markExpired(rescanReasonUploadURL)
|
||||
return "", ErrSessionExpired
|
||||
if intOf(raw["errcode"]) == errcodeSessionRejected {
|
||||
// Media upload is part of the send path, so the same rejected credential is
|
||||
// recorded here too rather than degrading into "no url returned".
|
||||
a.markRejected(rescanReasonUploadURL)
|
||||
return "", ErrSessionRejected
|
||||
}
|
||||
u := firstString(raw, "upload_url", "url", "uploadUrl", "cdn_url")
|
||||
if u == "" {
|
||||
|
||||
Reference in new issue
Block a user