From 9a8c4da0c429fcad4facaf0d8427aa699544afa2 Mon Sep 17 00:00:00 2001 From: chengyongru Date: Thu, 7 May 2026 11:19:51 +0800 Subject: [PATCH] refactor(logging): preserve tracebacks in remaining except blocks Follow-up to PR #3651: - Replace logger.error with logger.exception inside except blocks so stack traces are no longer lost: - providers/transcription.py (5 occurrences) - agent/tools/mcp.py (1 occurrence) - Replace stdlib logging.getLogger with loguru logger in providers/openai_compat_provider.py for consistency. --- nanobot/agent/tools/mcp.py | 2 +- nanobot/providers/openai_compat_provider.py | 3 +-- nanobot/providers/transcription.py | 10 +++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/nanobot/agent/tools/mcp.py b/nanobot/agent/tools/mcp.py index 6d4e7d6cd..0357e3c74 100644 --- a/nanobot/agent/tools/mcp.py +++ b/nanobot/agent/tools/mcp.py @@ -616,7 +616,7 @@ async def connect_mcp_servers( try: result = await connect_single_server(name, cfg) except Exception as e: - logger.error("MCP server '{}' connection failed: {}", name, e) + logger.exception("MCP server '{}' connection failed: {}", name, e) continue if result is not None and result[1] is not None: server_stacks[result[0]] = result[1] diff --git a/nanobot/providers/openai_compat_provider.py b/nanobot/providers/openai_compat_provider.py index 555d0e5e0..a983f63f5 100644 --- a/nanobot/providers/openai_compat_provider.py +++ b/nanobot/providers/openai_compat_provider.py @@ -24,8 +24,7 @@ if os.environ.get("LANGFUSE_SECRET_KEY") and importlib.util.find_spec("langfuse" from langfuse.openai import AsyncOpenAI else: if os.environ.get("LANGFUSE_SECRET_KEY"): - import logging - logging.getLogger(__name__).warning( + logger.warning( "LANGFUSE_SECRET_KEY is set but langfuse is not installed; " "install with `pip install langfuse` to enable tracing" ) diff --git a/nanobot/providers/transcription.py b/nanobot/providers/transcription.py index b4c71929e..9adf2e6d2 100644 --- a/nanobot/providers/transcription.py +++ b/nanobot/providers/transcription.py @@ -45,7 +45,7 @@ async def _post_transcription_with_retry( try: data = path.read_bytes() except OSError as e: - logger.error("{} transcription error: cannot read audio file: {}", provider_label, e) + logger.exception("{} transcription error: cannot read audio file: {}", provider_label, e) return "" headers = {"Authorization": f"Bearer {api_key}"} @@ -70,7 +70,7 @@ async def _post_transcription_with_retry( ) await asyncio.sleep(_BACKOFF_S[attempt]) continue - logger.error( + logger.exception( "{} transcription error after {} attempts: {}", provider_label, _MAX_RETRIES + 1, @@ -78,7 +78,7 @@ async def _post_transcription_with_retry( ) return "" except Exception as e: - logger.error("{} transcription error: {}", provider_label, e) + logger.exception("{} transcription error: {}", provider_label, e) return "" if response.status_code in _RETRYABLE_STATUS and attempt < _MAX_RETRIES: @@ -95,13 +95,13 @@ async def _post_transcription_with_retry( try: response.raise_for_status() except Exception as e: - logger.error("{} transcription error: {}", provider_label, e) + logger.exception("{} transcription error: {}", provider_label, e) return "" try: payload = response.json() except Exception as e: - logger.error( + logger.exception( "{} transcription error: malformed response body: {}", provider_label, e,