mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-16 14:32:34 +00:00
fix(telegram): classify PTB heartbeat transport errors
This commit is contained in:
parent
54e1864577
commit
97fb9e1f62
1 changed files with 31 additions and 18 deletions
|
|
@ -1175,12 +1175,23 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
|
||||
@staticmethod
|
||||
def _looks_like_network_error(error: Exception) -> bool:
|
||||
"""Return True for transient network errors that warrant a reconnect attempt."""
|
||||
"""Return True for transient transport failures that warrant reconnect."""
|
||||
name = error.__class__.__name__.lower()
|
||||
if name in {"badrequest", "invalidtoken", "forbidden", "retryafter"}:
|
||||
return False
|
||||
if name in {"networkerror", "timedout", "connectionerror"}:
|
||||
return True
|
||||
try:
|
||||
from telegram.error import NetworkError, TimedOut
|
||||
from telegram.error import (
|
||||
BadRequest,
|
||||
Forbidden,
|
||||
InvalidToken,
|
||||
NetworkError,
|
||||
RetryAfter,
|
||||
TimedOut,
|
||||
)
|
||||
if isinstance(error, (BadRequest, InvalidToken, Forbidden, RetryAfter)):
|
||||
return False
|
||||
if isinstance(error, (NetworkError, TimedOut)):
|
||||
return True
|
||||
except ImportError:
|
||||
|
|
@ -2204,17 +2215,11 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
except asyncio.CancelledError:
|
||||
return
|
||||
except (asyncio.TimeoutError, OSError) as probe_err:
|
||||
logger.warning(
|
||||
"[%s] Polling heartbeat probe failed (%s); triggering reconnect",
|
||||
self.name, probe_err,
|
||||
)
|
||||
if self._polling_error_task and not self._polling_error_task.done():
|
||||
continue # reconnect already in progress
|
||||
loop = asyncio.get_running_loop()
|
||||
self._polling_error_task = loop.create_task(
|
||||
self._handle_polling_network_error(probe_err)
|
||||
)
|
||||
except Exception:
|
||||
self._schedule_polling_recovery(probe_err, reason="heartbeat probe")
|
||||
except Exception as probe_err:
|
||||
if self._looks_like_network_error(probe_err):
|
||||
self._schedule_polling_recovery(probe_err, reason="heartbeat probe")
|
||||
continue
|
||||
# Non-connectivity errors (e.g. TelegramError 401) are not
|
||||
# CLOSE-WAIT symptoms — let PTB's own handlers surface them.
|
||||
pass
|
||||
|
|
@ -3192,10 +3197,6 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
# Start polling — retry initialize() for transient TLS resets.
|
||||
# Each attempt is capped by _init_timeout so a single unreachable
|
||||
# fallback-IP chain can't block startup indefinitely.
|
||||
try:
|
||||
from telegram.error import NetworkError, TimedOut
|
||||
except ImportError:
|
||||
NetworkError = TimedOut = OSError # type: ignore[misc,assignment]
|
||||
_max_connect = 8
|
||||
_init_timeout = _env_float("HERMES_TELEGRAM_INIT_TIMEOUT", 30.0)
|
||||
for _attempt in range(_max_connect):
|
||||
|
|
@ -3230,7 +3231,19 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
f"({_init_timeout:.0f}s each). Check network connectivity to api.telegram.org "
|
||||
f"or set HERMES_TELEGRAM_HTTP_CONNECT_TIMEOUT to a lower value."
|
||||
)
|
||||
except (NetworkError, TimedOut, OSError) as init_err:
|
||||
except OSError as init_err:
|
||||
if _attempt < _max_connect - 1:
|
||||
wait = min(2 ** _attempt, 15)
|
||||
logger.warning(
|
||||
"[%s] Connect attempt %d/%d failed: %s — retrying in %ds",
|
||||
self.name, _attempt + 1, _max_connect, init_err, wait,
|
||||
)
|
||||
await asyncio.sleep(wait)
|
||||
else:
|
||||
raise
|
||||
except Exception as init_err:
|
||||
if not self._looks_like_network_error(init_err):
|
||||
raise
|
||||
if _attempt < _max_connect - 1:
|
||||
wait = min(2 ** _attempt, 15)
|
||||
logger.warning(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue