mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-29 06:31:32 +00:00
Closes #31066. Closes #31110. An unhandled `telegram.error.TimedOut` (or peer `NetworkError` / `httpx` connection error) propagating to the asyncio event loop killed the entire gateway process, taking down every profile attached to the same runner. systemd restarted the service after ~5s but the active conversation turn was lost. Public adapter methods (`adapter.send`, `adapter.edit_message`, `adapter.send_voice`, …) are individually try/except-wrapped on current main, but at least one async path was reaching the loop with TimedOut unhandled — the report's traceback ends at the deepest httpx frame and doesn't pinpoint the caller. Rather than audit 30+ call sites blind, install a loop-level safety net: `_gateway_loop_exception_handler` is set as the loop's exception handler in `start_gateway()` after `asyncio.get_running_loop()`. It classifies the exception via `_is_transient_network_error()` (walks the __cause__/__context__ chain, matches on class name so the test suite doesn't need the real telegram/httpx packages installed). Transient errors are logged at WARNING with full traceback so the originating call site stays diagnosable; everything else forwards to `loop.default_exception_handler` so real bugs still surface. Tests cover the classifier (known transients accepted, real bugs rejected, cause/context chain unwrap, cyclic-cause termination) and the handler (swallow + log warning, forward unknowns, missing-exception context). One end-to-end test schedules an orphan task raising TimedOut and asserts `asyncio.run` returns cleanly. |
||
|---|---|---|
| .. | ||
| assets | ||
| builtin_hooks | ||
| platforms | ||
| __init__.py | ||
| channel_directory.py | ||
| config.py | ||
| delivery.py | ||
| display_config.py | ||
| hooks.py | ||
| memory_monitor.py | ||
| mirror.py | ||
| pairing.py | ||
| platform_registry.py | ||
| restart.py | ||
| run.py | ||
| runtime_footer.py | ||
| session.py | ||
| session_context.py | ||
| shutdown_forensics.py | ||
| slash_access.py | ||
| status.py | ||
| sticker_cache.py | ||
| stream_consumer.py | ||
| whatsapp_identity.py | ||