From 6b93a940deef000df118ced1ff3a32d5b64d12ab Mon Sep 17 00:00:00 2001 From: sh <37271604+shumvgolove@users.noreply.github.com> Date: Tue, 12 May 2026 13:26:15 +0000 Subject: [PATCH] simplex-chat-python: don't log routine async chat errors as ERROR (#6971) Chat errors emitted via the Haskell `eToView` path (e.g. agent errors on stale connections after a peer deletes a chat) were caught by the broad `except Exception` arm in the bot receive loop, producing an ERROR log with a full traceback for routine soft errors. Match the desktop client policy (SimpleXAPI.kt:3332-3340): catch ChatAPIError separately, escalate CRITICAL agent errors to ERROR, log the rest at DEBUG. --- .../src/simplex_chat/bot.py | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/simplex-chat-python/src/simplex_chat/bot.py b/packages/simplex-chat-python/src/simplex_chat/bot.py index 39709deee6..7414f28b87 100644 --- a/packages/simplex-chat-python/src/simplex_chat/bot.py +++ b/packages/simplex-chat-python/src/simplex_chat/bot.py @@ -12,7 +12,7 @@ from typing import Any, Generic, Literal, TypeVar, overload from . import util from .api import ChatApi, Db -from .core import MigrationConfirmation +from .core import ChatAPIError, MigrationConfirmation from .filters import compile_message_filter from .types import CEvt, T @@ -365,6 +365,26 @@ class Bot: event = await self.api.recv_chat_event(wait_us=500_000) except asyncio.CancelledError: raise + except ChatAPIError as e: + # Async chat errors emitted via the Haskell `eToView` path — + # routine soft errors (stale connections after a peer deletes + # a chat, file cleanup failures, etc.) intermixed with + # CRITICAL agent failures the operator must see. Mirror the + # desktop policy in SimpleXAPI.kt:3332-3340: escalate + # CRITICAL agent errors, keep everything else at debug. + chat_err: Any = e.chat_error or {} + agent_err: Any = ( + chat_err.get("agentError", {}) if chat_err.get("type") == "errorAgent" else {} + ) + if agent_err.get("type") == "CRITICAL": + log.error( + "chat agent CRITICAL: %s (offerRestart=%s)", + agent_err.get("criticalErr"), + agent_err.get("offerRestart"), + ) + else: + log.debug("chat event error: %s", chat_err.get("type")) + continue except Exception: log.exception("recv_chat_event failed") # Bound the spin rate when the FFI is wedged on a persistent