mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-04-05 02:42:41 +00:00
fix(telegram): shorten polling network errors
This commit is contained in:
parent
b9ee236ca1
commit
549e5ea8e2
@ -12,7 +12,7 @@ from typing import Any, Literal
|
||||
from loguru import logger
|
||||
from pydantic import Field
|
||||
from telegram import BotCommand, ReactionTypeEmoji, ReplyParameters, Update
|
||||
from telegram.error import BadRequest, TimedOut
|
||||
from telegram.error import BadRequest, NetworkError, TimedOut
|
||||
from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters
|
||||
from telegram.request import HTTPXRequest
|
||||
|
||||
@ -325,7 +325,8 @@ class TelegramChannel(BaseChannel):
|
||||
# Start polling (this runs until stopped)
|
||||
await self._app.updater.start_polling(
|
||||
allowed_updates=["message"],
|
||||
drop_pending_updates=False # Process pending messages on startup
|
||||
drop_pending_updates=False, # Process pending messages on startup
|
||||
error_callback=self._on_polling_error,
|
||||
)
|
||||
|
||||
# Keep running until stopped
|
||||
@ -974,14 +975,36 @@ class TelegramChannel(BaseChannel):
|
||||
except Exception as e:
|
||||
logger.debug("Typing indicator stopped for {}: {}", chat_id, e)
|
||||
|
||||
@staticmethod
|
||||
def _format_telegram_error(exc: Exception) -> str:
|
||||
"""Return a short, readable error summary for logs."""
|
||||
text = str(exc).strip()
|
||||
if text:
|
||||
return text
|
||||
if exc.__cause__ is not None:
|
||||
cause = exc.__cause__
|
||||
cause_text = str(cause).strip()
|
||||
if cause_text:
|
||||
return f"{exc.__class__.__name__} ({cause_text})"
|
||||
return f"{exc.__class__.__name__} ({cause.__class__.__name__})"
|
||||
return exc.__class__.__name__
|
||||
|
||||
def _on_polling_error(self, exc: Exception) -> None:
|
||||
"""Keep long-polling network failures to a single readable line."""
|
||||
summary = self._format_telegram_error(exc)
|
||||
if isinstance(exc, (NetworkError, TimedOut)):
|
||||
logger.warning("Telegram polling network issue: {}", summary)
|
||||
else:
|
||||
logger.error("Telegram polling error: {}", summary)
|
||||
|
||||
async def _on_error(self, update: object, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Log polling / handler errors instead of silently swallowing them."""
|
||||
from telegram.error import NetworkError, TimedOut
|
||||
|
||||
summary = self._format_telegram_error(context.error)
|
||||
|
||||
if isinstance(context.error, (NetworkError, TimedOut)):
|
||||
logger.warning("Telegram network issue: {}", str(context.error))
|
||||
logger.warning("Telegram network issue: {}", summary)
|
||||
else:
|
||||
logger.error("Telegram error: {}", context.error)
|
||||
logger.error("Telegram error: {}", summary)
|
||||
|
||||
def _get_extension(
|
||||
self,
|
||||
|
||||
@ -32,8 +32,10 @@ class _FakeHTTPXRequest:
|
||||
class _FakeUpdater:
|
||||
def __init__(self, on_start_polling) -> None:
|
||||
self._on_start_polling = on_start_polling
|
||||
self.start_polling_kwargs = None
|
||||
|
||||
async def start_polling(self, **kwargs) -> None:
|
||||
self.start_polling_kwargs = kwargs
|
||||
self._on_start_polling()
|
||||
|
||||
|
||||
@ -184,6 +186,7 @@ async def test_start_creates_separate_pools_with_proxy(monkeypatch) -> None:
|
||||
assert poll_req.kwargs["connection_pool_size"] == 4
|
||||
assert builder.request_value is api_req
|
||||
assert builder.get_updates_request_value is poll_req
|
||||
assert callable(app.updater.start_polling_kwargs["error_callback"])
|
||||
assert any(cmd.command == "status" for cmd in app.bot.commands)
|
||||
assert any(cmd.command == "dream" for cmd in app.bot.commands)
|
||||
assert any(cmd.command == "dream-log" for cmd in app.bot.commands)
|
||||
@ -307,6 +310,26 @@ async def test_on_error_logs_network_issues_as_warning(monkeypatch) -> None:
|
||||
assert recorded == [("warning", "Telegram network issue: proxy disconnected")]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_on_error_summarizes_empty_network_error(monkeypatch) -> None:
|
||||
from telegram.error import NetworkError
|
||||
|
||||
channel = TelegramChannel(
|
||||
TelegramConfig(enabled=True, token="123:abc", allow_from=["*"]),
|
||||
MessageBus(),
|
||||
)
|
||||
recorded: list[tuple[str, str]] = []
|
||||
|
||||
monkeypatch.setattr(
|
||||
"nanobot.channels.telegram.logger.warning",
|
||||
lambda message, error: recorded.append(("warning", message.format(error))),
|
||||
)
|
||||
|
||||
await channel._on_error(object(), SimpleNamespace(error=NetworkError("")))
|
||||
|
||||
assert recorded == [("warning", "Telegram network issue: NetworkError")]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_on_error_keeps_non_network_exceptions_as_error(monkeypatch) -> None:
|
||||
channel = TelegramChannel(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user