feat(dufe): auto 模式 attempts 改为逐次完整记录

- entry.attempts 由计数改为列表: 每次尝试 {n, success, message}
- relogin 后立即重试的那次带 "relogin": true 标记
- 成功/失败(重试用尽)两种情况都完整携带全部尝试记录
This commit is contained in:
RRRosmontis
2026-09-23 12:03:30 +08:00
parent 9b9c501fa9
commit c3f8d64f0e
@@ -848,7 +848,8 @@ def _signin_one_with_retry(username, password, row, sess, token):
token 疑似失效(上游错误/登录错)时重新登录一次后立即重试(对齐 bot refresh 语义)。
与 bot complete_signin 一致:除限流(外层中断)外,任何未确认成功都消耗重试次数;
重试用尽记最终失败。返回 (entry, sess, token)。"""
重试用尽记最终失败。entry["attempts"] 为逐次完整记录列表(每次的结果与原因,
relogin 后立即重试的那次带 "relogin": true)。返回 (entry, sess, token)。"""
link = row["link"]
base = {
"activityKey": row.get("signin_activity_key"),
@@ -859,16 +860,25 @@ def _signin_one_with_retry(username, password, row, sess, token):
}
attempts = 0
refreshed = False
relogin_before_next = False # 上一次迭代发生了重登录,下一次尝试标记 relogin
last_err = "unknown error"
last_data = None
attempt_log = [] # 逐次记录:{"n", "success", "message"[, "relogin"]}
while attempts < MAX_SIGNIN_ATTEMPTS:
attempts += 1
record = {"n": attempts}
if relogin_before_next:
record["relogin"] = True
relogin_before_next = False
try:
data = fetch_sign_in_info(username, password, link, do_commit=True,
sess=sess, token=token)
last_data = data
commit = data.get("commit")
if isinstance(commit, dict) and commit.get("success") is True:
record["success"] = True
record["message"] = "签到成功"
attempt_log.append(record)
entry = dict(base)
entry.update({
"type": data.get("type"),
@@ -878,12 +888,14 @@ def _signin_one_with_retry(username, password, row, sess, token):
"status": data.get("status"),
"success": True,
"message": "签到成功",
"attempts": attempts,
"attempts": attempt_log,
})
return entry, sess, token
message = ((commit or {}).get("message")
or "no commit result returned")
last_err = str(message)
record["success"] = False
record["message"] = last_err
except RateLimitedError:
raise
except (UpstreamError, AuthError) as e:
@@ -892,14 +904,25 @@ def _signin_one_with_retry(username, password, row, sess, token):
refreshed = True
try:
sess, token = login(username, password)
record["success"] = False
record["message"] = str(e) or type(e).__name__
attempt_log.append(record)
relogin_before_next = True
continue
except Exception:
pass # 重登录也失败:落入常规退避重试
last_err = str(e) or type(e).__name__
record["success"] = False
record["message"] = last_err
except NoSignInCodeError as e:
last_err = str(e)
record["success"] = False
record["message"] = last_err
except Exception as e:
last_err = safe_error(e)
record["success"] = False
record["message"] = last_err
attempt_log.append(record)
if attempts < MAX_SIGNIN_ATTEMPTS:
time.sleep(SIGNIN_BACKOFF[min(attempts - 1, len(SIGNIN_BACKOFF) - 1)])
entry = dict(base)
@@ -913,7 +936,7 @@ def _signin_one_with_retry(username, password, row, sess, token):
})
entry.update({"success": False,
"message": "签到失败(重试 %d 次): %s" % (attempts, last_err),
"attempts": attempts})
"attempts": attempt_log})
return entry, sess, token