From fd9aaa193b6b6e8cfd71e92312fc87488c75276e Mon Sep 17 00:00:00 2001 From: ChemaVX Date: Tue, 9 Jun 2026 18:39:55 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20watch=20diff=20=E2=80=94=20env=C3=ADo=20?= =?UTF-8?q?con=20fallback=20a=20texto=20plano=20y=20task=20no=20silencioso?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit El resumen de diff generado por Claude se enviaba con parse_mode=MARKDOWN; texto libre con entidades desbalanceadas provocaba BadRequest y el mensaje no llegaba. Además el send_message estaba fuera del try/except de _task y el task se retenía en _active_tasks sin await, así que la excepción se tragaba sin log alguno. - _safe_send(): intenta Markdown y reintenta en texto plano si falla - _task: except de nivel superior que loguea cualquier fallo Co-Authored-By: Claude Opus 4.8 (1M context) --- src/bot/bot.py | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/bot/bot.py b/src/bot/bot.py index 5da2c19..0be9c17 100644 --- a/src/bot/bot.py +++ b/src/bot/bot.py @@ -816,6 +816,23 @@ async def _purge_on_startup(app: Application) -> None: await db_conn.close() +async def _safe_send(bot, chat_id, text: str): + """Envía un mensaje, con fallback a texto plano si falla el parseo Markdown. + + Los resúmenes generados por Claude suelen contener entidades Markdown + desbalanceadas (*, _, [, `) que hacen que Telegram rechace el mensaje con + BadRequest. Sin este fallback, el envío fallaba en silencio. + """ + try: + await bot.send_message(chat_id, text, parse_mode=ParseMode.MARKDOWN) + except Exception as e: + logger.warning("Envío Markdown falló, reintentando en texto plano", error=str(e)) + try: + await bot.send_message(chat_id, text) + except Exception as e2: + logger.error("Envío en texto plano también falló", chat_id=chat_id, error=str(e2)) + + async def _scheduler_loop(app: Application): while True: db_conn = None @@ -858,24 +875,23 @@ async def _scheduler_loop(app: Application): ) if summary: - await app.bot.send_message( - c, summary, parse_mode=ParseMode.MARKDOWN - ) + await _safe_send(app.bot, c, summary) else: - await app.bot.send_message( - c, - f"🔄 *{t}* — sin novedades significativas esta vez.", - parse_mode=ParseMode.MARKDOWN + await _safe_send( + app.bot, c, + f"🔄 *{t}* — sin novedades significativas esta vez." ) + except Exception as e: + logger.error("Tarea programada falló", + topic=t, session_id=s, error=str(e)) finally: await inner_db_conn.close() task = asyncio.create_task(_task()) _active_tasks[chat_id] = task - await app.bot.send_message( - chat_id, - f"🔄 Investigación automática iniciada: `{topic}`", - parse_mode=ParseMode.MARKDOWN + await _safe_send( + app.bot, chat_id, + f"🔄 Investigación automática iniciada: `{topic}`" ) except Exception as e: logger.warning("Scheduler loop error", error=str(e))