From 3c6cafd62d27ff6ac51bb058c82a2b062f6b8135 Mon Sep 17 00:00:00 2001 From: Andre K Date: Thu, 16 Apr 2026 08:35:30 +0800 Subject: [PATCH] fix: add error handler and resilient reply to prevent crash on deleted messages --- main.py | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/main.py b/main.py index dd75908..5281088 100644 --- a/main.py +++ b/main.py @@ -11,6 +11,7 @@ import subprocess from openai import OpenAI from telegram import BotCommand, Update +from telegram.error import BadRequest, TimedOut from telegram.ext import ( ApplicationBuilder, CommandHandler, @@ -345,7 +346,7 @@ async def handle_message(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None ) except Exception as e: log.error("OpenAI API error: %s", e) - await update.message.reply_text(f"Sorry, I hit an error: {e}") + await _safe_reply(update, f"Sorry, I hit an error: {e}") return choice = response.choices[0] @@ -381,14 +382,31 @@ async def handle_message(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None if len(messages) > 60: messages[:] = messages[:1] + messages[-40:] - await update.message.reply_text(msg.content) + await _safe_reply(update, msg.content) return - await update.message.reply_text( - "I ran out of steps — please try again with a simpler request." + await _safe_reply( + update, "I ran out of steps — please try again with a simpler request." ) +async def _safe_reply(update: Update, text: str, **kwargs) -> None: + """Reply to a message, falling back to send_message if the original is gone.""" + try: + await update.message.reply_text(text, **kwargs) + except BadRequest: + log.warning("Could not reply to message, sending without reply") + await update.effective_chat.send_message(text, **kwargs) + + +async def _error_handler(update: object, context: ContextTypes.DEFAULT_TYPE) -> None: + """Log errors and keep the bot running.""" + if isinstance(context.error, TimedOut): + log.warning("Telegram request timed out") + return + log.error("Unhandled exception: %s", context.error, exc_info=context.error) + + # --------------------------------------------------------------------------- # Main # --------------------------------------------------------------------------- @@ -397,13 +415,16 @@ def main() -> None: app.add_handler(CommandHandler("start", cmd_start)) app.add_handler(CommandHandler("reset", cmd_reset)) app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message)) + app.add_error_handler(_error_handler) # Register bot commands for the / menu async def post_init(application) -> None: - await application.bot.set_my_commands([ - BotCommand("start", "Show welcome message"), - BotCommand("reset", "Reset conversation"), - ]) + await application.bot.set_my_commands( + [ + BotCommand("start", "Show welcome message"), + BotCommand("reset", "Reset conversation"), + ] + ) log.info("Bot commands registered") app.post_init = post_init