feat: improve telegram error handling
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
@@ -8,6 +9,16 @@ import httpx
|
|||||||
logger = logging.getLogger(__name__)
|
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:
|
class TelegramClient:
|
||||||
"""
|
"""
|
||||||
Minimal Telegram Bot API client.
|
Minimal Telegram Bot API client.
|
||||||
@@ -26,10 +37,22 @@ class TelegramClient:
|
|||||||
try:
|
try:
|
||||||
logger.debug("[telegram] request %s: %s", method, json_data)
|
logger.debug("[telegram] request %s: %s", method, json_data)
|
||||||
resp = await self._client.post(f"{self._base}/{method}", json=json_data)
|
resp = await self._client.post(f"{self._base}/{method}", json=json_data)
|
||||||
resp.raise_for_status()
|
payload: dict[str, Any] | None = None
|
||||||
payload = resp.json()
|
try:
|
||||||
|
payload = resp.json()
|
||||||
|
except Exception:
|
||||||
|
resp.raise_for_status()
|
||||||
|
raise
|
||||||
if not payload.get("ok"):
|
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)
|
logger.debug("[telegram] response %s: %s", method, payload)
|
||||||
return payload["result"]
|
return payload["result"]
|
||||||
except httpx.HTTPError as e:
|
except httpx.HTTPError as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user