From 70928d5bdfbe58f5126b45a9f0cffaa9645e8150 Mon Sep 17 00:00:00 2001 From: banteg <4562643+banteg@users.noreply.github.com> Date: Mon, 29 Dec 2025 13:51:33 +0400 Subject: [PATCH] feat: improve telegram error handling --- .../codex_telegram_bridge/telegram_client.py | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/codex_telegram_bridge/src/codex_telegram_bridge/telegram_client.py b/codex_telegram_bridge/src/codex_telegram_bridge/telegram_client.py index 0f04ca2..6eec012 100644 --- a/codex_telegram_bridge/src/codex_telegram_bridge/telegram_client.py +++ b/codex_telegram_bridge/src/codex_telegram_bridge/telegram_client.py @@ -1,5 +1,6 @@ from __future__ import annotations +import asyncio import logging from typing import Any @@ -8,6 +9,16 @@ import httpx logger = logging.getLogger(__name__) +class TelegramAPIError(RuntimeError): + def __init__( + self, method: str, payload: dict[str, Any], status_code: int | None + ) -> None: + desc = payload.get("description") or str(payload) + super().__init__(f"{method} failed: {desc}") + self.payload = payload + self.status_code = status_code + + class TelegramClient: """ Minimal Telegram Bot API client. @@ -26,10 +37,22 @@ class TelegramClient: try: logger.debug("[telegram] request %s: %s", method, json_data) resp = await self._client.post(f"{self._base}/{method}", json=json_data) - resp.raise_for_status() - payload = resp.json() + payload: dict[str, Any] | None = None + try: + payload = resp.json() + except Exception: + resp.raise_for_status() + raise if not payload.get("ok"): - raise RuntimeError(f"Telegram API error: {payload}") + params = payload.get("parameters") or {} + retry_after = params.get("retry_after") + if resp.status_code == 429 and isinstance(retry_after, int): + logger.warning( + "[telegram] 429 retry_after=%s method=%s", retry_after, method + ) + await asyncio.sleep(retry_after) + return await self._post(method, json_data) + raise TelegramAPIError(method, payload, resp.status_code) logger.debug("[telegram] response %s: %s", method, payload) return payload["result"] except httpx.HTTPError as e: