fix: add error handler and resilient reply to prevent crash on deleted messages

This commit is contained in:
Andre Kamarudin 2026-04-16 08:35:30 +08:00
parent b625ed237a
commit 3c6cafd62d

37
main.py
View file

@ -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