stop infinite retry loop when user blocks the bot or deactivates account
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 11s

Forbidden from send_message was falling into the generic error handler,
which resets consecutive_errors to 0 right before the send attempt — so
backoff never grew past 60s and the pair retried forever, wasting request
queue capacity needed by other users' real periodic checks.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
vrubelroman 2026-07-05 20:00:56 +00:00
parent 619c00aa06
commit 08f97d413a

View file

@ -13,6 +13,7 @@ from telegram.ext import (
MessageHandler, filters, ContextTypes, ConversationHandler, MessageHandler, filters, ContextTypes, ConversationHandler,
PicklePersistence PicklePersistence
) )
from telegram.error import Forbidden
import config import config
from config import ( from config import (
@ -1822,11 +1823,25 @@ class LichessBot:
if not self.application: if not self.application:
raise RuntimeError(f"Application not initialized, cannot send notification for {gamer['username']} to user {user_id}") raise RuntimeError(f"Application not initialized, cannot send notification for {gamer['username']} to user {user_id}")
# Forbidden (user blocked the bot) is permanent, not worth retrying:
# without this, consecutive_errors gets reset to 0 above right before
# this call succeeds/fails, so the outer handler's backoff never grows
# past 60s and this pair retries forever, wasting queue capacity that
# other users' real checks need.
try:
await self.application.bot.send_message( await self.application.bot.send_message(
chat_id=user_id, chat_id=user_id,
text=notification, text=notification,
parse_mode='Markdown' parse_mode='Markdown'
) )
except Forbidden:
logger.warning(f"🚫 User {user_id} blocked the bot; stopping periodic monitoring for {gamer['username']}")
self.db.set_user_gamer_period(user_id, gamer['id'], 0)
if task_key in self.periodic_tasks:
del self.periodic_tasks[task_key]
if task_key in self.period_start_times:
del self.period_start_times[task_key]
return
logger.info(f"✅ Sent periodic notification for {gamer['username']} to user {user_id}") logger.info(f"✅ Sent periodic notification for {gamer['username']} to user {user_id}")
# Increment periodic notification counter # Increment periodic notification counter
self.counters.increment('periodic_notification') self.counters.increment('periodic_notification')