diff --git a/src/config.py b/src/config.py
index 2aa0d5d..c27b17c 100644
--- a/src/config.py
+++ b/src/config.py
@@ -393,7 +393,8 @@ def check_ollama_model_available(model_name: str) -> bool:
model_name == m or model_name == m.split(":")[0] or m.startswith(model_name)
for m in models
)
- except Exception:
+ except Exception as exc:
+ _startup_logger.debug("Ollama model check failed: %s", exc)
return False
diff --git a/src/dashboard/app.py b/src/dashboard/app.py
index 28360d2..a7555fc 100644
--- a/src/dashboard/app.py
+++ b/src/dashboard/app.py
@@ -510,7 +510,8 @@ async def swarm_live(websocket: WebSocket):
while True:
# Keep connection alive; events are pushed via ws_mgr.broadcast()
await websocket.receive_text()
- except Exception:
+ except Exception as exc:
+ logger.debug("WebSocket disconnect error: %s", exc)
ws_mgr.disconnect(websocket)
@@ -532,7 +533,8 @@ async def swarm_agents_sidebar():
f""
)
return "\n".join(lines) if lines else '
No agents configured
'
- except Exception:
+ except Exception as exc:
+ logger.debug("Agents sidebar error: %s", exc)
return 'Agents unavailable
'
diff --git a/src/dashboard/middleware/csrf.py b/src/dashboard/middleware/csrf.py
index e3a8320..d607e1f 100644
--- a/src/dashboard/middleware/csrf.py
+++ b/src/dashboard/middleware/csrf.py
@@ -5,6 +5,7 @@ to protect state-changing endpoints from cross-site request attacks.
"""
import hmac
+import logging
import secrets
from collections.abc import Callable
from functools import wraps
@@ -16,6 +17,8 @@ from starlette.responses import JSONResponse, Response
# Module-level set to track exempt routes
_exempt_routes: set[str] = set()
+logger = logging.getLogger(__name__)
+
def csrf_exempt(endpoint: Callable) -> Callable:
"""Decorator to mark an endpoint as exempt from CSRF validation.
@@ -278,7 +281,8 @@ class CSRFMiddleware(BaseHTTPMiddleware):
form_token = form_data.get(self.form_field)
if form_token and validate_csrf_token(str(form_token), csrf_cookie):
return True
- except Exception:
+ except Exception as exc:
+ logger.debug("CSRF form parsing error: %s", exc)
# Error parsing form data, treat as invalid
pass
diff --git a/src/dashboard/middleware/request_logging.py b/src/dashboard/middleware/request_logging.py
index 1084d48..8d6e8f0 100644
--- a/src/dashboard/middleware/request_logging.py
+++ b/src/dashboard/middleware/request_logging.py
@@ -115,7 +115,8 @@ class RequestLoggingMiddleware(BaseHTTPMiddleware):
"duration_ms": f"{duration_ms:.0f}",
},
)
- except Exception:
+ except Exception as exc:
+ logger.debug("Escalation logging error: %s", exc)
pass # never let escalation break the request
# Re-raise the exception
diff --git a/src/dashboard/middleware/security_headers.py b/src/dashboard/middleware/security_headers.py
index 9cd5015..c0ae043 100644
--- a/src/dashboard/middleware/security_headers.py
+++ b/src/dashboard/middleware/security_headers.py
@@ -4,10 +4,14 @@ Adds common security headers to all HTTP responses to improve
application security posture against various attacks.
"""
+import logging
+
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import Response
+logger = logging.getLogger(__name__)
+
class SecurityHeadersMiddleware(BaseHTTPMiddleware):
"""Middleware to add security headers to all responses.
@@ -130,12 +134,8 @@ class SecurityHeadersMiddleware(BaseHTTPMiddleware):
"""
try:
response = await call_next(request)
- except Exception:
- import logging
-
- logging.getLogger(__name__).debug(
- "Upstream error in security headers middleware", exc_info=True
- )
+ except Exception as exc:
+ logger.debug("Upstream error in security headers middleware: %s", exc)
from starlette.responses import PlainTextResponse
response = PlainTextResponse("Internal Server Error", status_code=500)
diff --git a/src/dashboard/routes/agents.py b/src/dashboard/routes/agents.py
index b7d34d1..6a758a9 100644
--- a/src/dashboard/routes/agents.py
+++ b/src/dashboard/routes/agents.py
@@ -220,7 +220,8 @@ async def reject_tool(request: Request, approval_id: str):
# Resume so the agent knows the tool was rejected
try:
await continue_chat(pending["run_output"])
- except Exception:
+ except Exception as exc:
+ logger.warning("Agent tool rejection error: %s", exc)
pass
reject(approval_id)
diff --git a/src/dashboard/routes/briefing.py b/src/dashboard/routes/briefing.py
index 16bbfc2..c72a3a8 100644
--- a/src/dashboard/routes/briefing.py
+++ b/src/dashboard/routes/briefing.py
@@ -27,7 +27,8 @@ async def get_briefing(request: Request):
"""Return today's briefing page (generated or cached)."""
try:
briefing = briefing_engine.get_or_generate()
- except Exception:
+ except Exception as exc:
+ logger.debug("Briefing generation failed: %s", exc)
logger.exception("Briefing generation failed")
now = datetime.now(UTC)
briefing = Briefing(
diff --git a/src/dashboard/routes/chat_api.py b/src/dashboard/routes/chat_api.py
index 9b595d4..9e047a9 100644
--- a/src/dashboard/routes/chat_api.py
+++ b/src/dashboard/routes/chat_api.py
@@ -51,7 +51,8 @@ async def api_chat(request: Request):
try:
body = await request.json()
- except Exception:
+ except Exception as exc:
+ logger.warning("Chat API JSON parse error: %s", exc)
return JSONResponse(status_code=400, content={"error": "Invalid JSON"})
messages = body.get("messages")
diff --git a/src/dashboard/routes/experiments.py b/src/dashboard/routes/experiments.py
index 37b0be3..0b8b44e 100644
--- a/src/dashboard/routes/experiments.py
+++ b/src/dashboard/routes/experiments.py
@@ -30,8 +30,8 @@ async def experiments_page(request: Request):
history = []
try:
history = get_experiment_history(_workspace())
- except Exception:
- logger.debug("Failed to load experiment history", exc_info=True)
+ except Exception as exc:
+ logger.debug("Failed to load experiment history: %s", exc)
return templates.TemplateResponse(
request,
diff --git a/src/dashboard/routes/grok.py b/src/dashboard/routes/grok.py
index b6757fe..4b44316 100644
--- a/src/dashboard/routes/grok.py
+++ b/src/dashboard/routes/grok.py
@@ -52,8 +52,8 @@ async def grok_status(request: Request):
"estimated_cost_sats": backend.stats.estimated_cost_sats,
"errors": backend.stats.errors,
}
- except Exception:
- logger.debug("Failed to load Grok stats", exc_info=True)
+ except Exception as exc:
+ logger.warning("Failed to load Grok stats: %s", exc)
return templates.TemplateResponse(
request,
@@ -94,8 +94,8 @@ async def toggle_grok_mode(request: Request):
tool_name="grok_mode_toggle",
success=True,
)
- except Exception:
- logger.debug("Failed to log Grok toggle to Spark", exc_info=True)
+ except Exception as exc:
+ logger.warning("Failed to log Grok toggle to Spark: %s", exc)
return HTMLResponse(
_render_toggle_card(_grok_mode_active),
@@ -128,8 +128,8 @@ def _run_grok_query(message: str) -> dict:
sats = min(settings.grok_max_sats_per_query, 100)
ln.create_invoice(sats, f"Grok: {message[:50]}")
invoice_note = f" | {sats} sats"
- except Exception:
- logger.debug("Lightning invoice creation failed", exc_info=True)
+ except Exception as exc:
+ logger.warning("Lightning invoice creation failed: %s", exc)
try:
result = backend.run(message)
diff --git a/src/dashboard/routes/health.py b/src/dashboard/routes/health.py
index d4670ed..b9455b5 100644
--- a/src/dashboard/routes/health.py
+++ b/src/dashboard/routes/health.py
@@ -76,8 +76,8 @@ def _check_ollama_sync() -> DependencyStatus:
sovereignty_score=10,
details={"url": settings.ollama_url, "model": settings.ollama_model},
)
- except Exception:
- logger.debug("Ollama health check failed", exc_info=True)
+ except Exception as exc:
+ logger.debug("Ollama health check failed: %s", exc)
return DependencyStatus(
name="Ollama AI",
@@ -101,7 +101,8 @@ async def _check_ollama() -> DependencyStatus:
try:
result = await asyncio.to_thread(_check_ollama_sync)
- except Exception:
+ except Exception as exc:
+ logger.debug("Ollama async check failed: %s", exc)
result = DependencyStatus(
name="Ollama AI",
status="unavailable",
diff --git a/src/dashboard/routes/system.py b/src/dashboard/routes/system.py
index 86ac817..7c22bb9 100644
--- a/src/dashboard/routes/system.py
+++ b/src/dashboard/routes/system.py
@@ -144,5 +144,6 @@ async def api_notifications():
for e in events
]
)
- except Exception:
+ except Exception as exc:
+ logger.debug("System events fetch error: %s", exc)
return JSONResponse([])
diff --git a/src/dashboard/routes/voice.py b/src/dashboard/routes/voice.py
index 08dcc6f..00e7659 100644
--- a/src/dashboard/routes/voice.py
+++ b/src/dashboard/routes/voice.py
@@ -43,7 +43,8 @@ async def tts_status():
"available": voice_tts.available,
"voices": voice_tts.get_voices() if voice_tts.available else [],
}
- except Exception:
+ except Exception as exc:
+ logger.debug("Voice config error: %s", exc)
return {"available": False, "voices": []}
@@ -139,7 +140,8 @@ async def process_voice_input(
if voice_tts.available:
voice_tts.speak(response_text)
- except Exception:
+ except Exception as exc:
+ logger.debug("Voice TTS error: %s", exc)
pass
return {
diff --git a/src/infrastructure/error_capture.py b/src/infrastructure/error_capture.py
index 9053bcb..e6b18bb 100644
--- a/src/infrastructure/error_capture.py
+++ b/src/infrastructure/error_capture.py
@@ -87,7 +87,8 @@ def _get_git_context() -> dict:
).stdout.strip()
return {"branch": branch, "commit": commit}
- except Exception:
+ except Exception as exc:
+ logger.warning("Git info capture error: %s", exc)
return {"branch": "unknown", "commit": "unknown"}
@@ -199,7 +200,8 @@ def capture_error(
"title": title[:100],
},
)
- except Exception:
+ except Exception as exc:
+ logger.warning("Bug report screenshot error: %s", exc)
pass
except Exception as task_exc:
@@ -214,7 +216,8 @@ def capture_error(
message=f"{type(exc).__name__} in {source}: {str(exc)[:80]}",
category="system",
)
- except Exception:
+ except Exception as exc:
+ logger.warning("Bug report notification error: %s", exc)
pass
# 4. Record in session logger
@@ -226,7 +229,8 @@ def capture_error(
error=f"{type(exc).__name__}: {str(exc)}",
context=source,
)
- except Exception:
+ except Exception as exc:
+ logger.warning("Bug report session logging error: %s", exc)
pass
return task_id
diff --git a/src/infrastructure/router/cascade.py b/src/infrastructure/router/cascade.py
index e3aaea3..3b5e23a 100644
--- a/src/infrastructure/router/cascade.py
+++ b/src/infrastructure/router/cascade.py
@@ -304,7 +304,8 @@ class CascadeRouter:
url = provider.url or "http://localhost:11434"
response = requests.get(f"{url}/api/tags", timeout=5)
return response.status_code == 200
- except Exception:
+ except Exception as exc:
+ logger.debug("Ollama provider check error: %s", exc)
return False
elif provider.type == "airllm":
diff --git a/src/infrastructure/ws_manager/handler.py b/src/infrastructure/ws_manager/handler.py
index 9beb0bf..978a195 100644
--- a/src/infrastructure/ws_manager/handler.py
+++ b/src/infrastructure/ws_manager/handler.py
@@ -54,7 +54,8 @@ class WebSocketManager:
for event in list(self._event_history)[-20:]:
try:
await websocket.send_text(event.to_json())
- except Exception:
+ except Exception as exc:
+ logger.warning("WebSocket history send error: %s", exc)
break
def disconnect(self, websocket: WebSocket) -> None:
@@ -83,8 +84,8 @@ class WebSocketManager:
await ws.send_text(message)
except ConnectionError:
disconnected.append(ws)
- except Exception:
- logger.warning("Unexpected WebSocket send error", exc_info=True)
+ except Exception as exc:
+ logger.warning("Unexpected WebSocket send error: %s", exc)
disconnected.append(ws)
# Clean up dead connections
@@ -156,7 +157,8 @@ class WebSocketManager:
try:
await ws.send_text(message)
count += 1
- except Exception:
+ except Exception as exc:
+ logger.warning("WebSocket direct send error: %s", exc)
disconnected.append(ws)
# Clean up dead connections
diff --git a/src/integrations/chat_bridge/vendors/discord.py b/src/integrations/chat_bridge/vendors/discord.py
index 2defc69..6dfcea5 100644
--- a/src/integrations/chat_bridge/vendors/discord.py
+++ b/src/integrations/chat_bridge/vendors/discord.py
@@ -87,7 +87,8 @@ if _DISCORD_UI_AVAILABLE:
await action["target"].send(
f"Action `{action['tool_name']}` timed out and was auto-rejected."
)
- except Exception:
+ except Exception as exc:
+ logger.warning("Discord action timeout message error: %s", exc)
pass
@@ -186,7 +187,8 @@ class DiscordVendor(ChatPlatform):
if self._client and not self._client.is_closed():
try:
await self._client.close()
- except Exception:
+ except Exception as exc:
+ logger.warning("Discord client close error: %s", exc)
pass
self._client = None
@@ -330,7 +332,8 @@ class DiscordVendor(ChatPlatform):
if settings.discord_token:
return settings.discord_token
- except Exception:
+ except Exception as exc:
+ logger.warning("Discord token load error: %s", exc)
pass
# 2. Fall back to state file (set via /discord/setup endpoint)
@@ -458,7 +461,8 @@ class DiscordVendor(ChatPlatform):
req.reject(note="User rejected from Discord")
try:
await continue_chat(action["run_output"], action.get("session_id"))
- except Exception:
+ except Exception as exc:
+ logger.warning("Discord continue chat error: %s", exc)
pass
await interaction.response.send_message(
diff --git a/src/integrations/telegram_bot/bot.py b/src/integrations/telegram_bot/bot.py
index c427a3e..d8c6dbe 100644
--- a/src/integrations/telegram_bot/bot.py
+++ b/src/integrations/telegram_bot/bot.py
@@ -56,7 +56,8 @@ class TelegramBot:
from config import settings
return settings.telegram_token or None
- except Exception:
+ except Exception as exc:
+ logger.warning("Telegram token load error: %s", exc)
return None
def save_token(self, token: str) -> None:
diff --git a/src/spark/engine.py b/src/spark/engine.py
index 48f8264..89d59d1 100644
--- a/src/spark/engine.py
+++ b/src/spark/engine.py
@@ -358,7 +358,8 @@ def get_spark_engine() -> SparkEngine:
from config import settings
_spark_engine = SparkEngine(enabled=settings.spark_enabled)
- except Exception:
+ except Exception as exc:
+ logger.debug("Spark engine settings load error: %s", exc)
_spark_engine = SparkEngine(enabled=True)
return _spark_engine
diff --git a/src/spark/memory.py b/src/spark/memory.py
index a604d11..973f816 100644
--- a/src/spark/memory.py
+++ b/src/spark/memory.py
@@ -10,12 +10,15 @@ spark_events — raw event log (every swarm event)
spark_memories — consolidated insights extracted from event patterns
"""
+import logging
import sqlite3
import uuid
from dataclasses import dataclass
from datetime import UTC, datetime
from pathlib import Path
+logger = logging.getLogger(__name__)
+
DB_PATH = Path("data/spark.db")
# Importance thresholds
@@ -170,7 +173,8 @@ def record_event(
task_id=task_id or "",
agent_id=agent_id or "",
)
- except Exception:
+ except Exception as exc:
+ logger.debug("Spark event log error: %s", exc)
pass # Graceful — don't break spark if event_log is unavailable
return event_id
diff --git a/src/timmy/agent.py b/src/timmy/agent.py
index 911c3bd..36063bc 100644
--- a/src/timmy/agent.py
+++ b/src/timmy/agent.py
@@ -358,7 +358,8 @@ class TimmyWithMemory:
if name:
self.memory.update_user_fact("Name", name)
self.memory.record_decision(f"Learned user's name: {name}")
- except Exception:
+ except Exception as exc:
+ logger.warning("User name extraction failed: %s", exc)
pass # Best-effort extraction
def end_session(self, summary: str = "Session completed") -> None:
diff --git a/src/timmy/agentic_loop.py b/src/timmy/agentic_loop.py
index bff1c6a..df27c5d 100644
--- a/src/timmy/agentic_loop.py
+++ b/src/timmy/agentic_loop.py
@@ -332,5 +332,6 @@ async def _broadcast_progress(event: str, data: dict) -> None:
from infrastructure.ws_manager.handler import ws_manager
await ws_manager.broadcast(event, data)
- except Exception:
+ except Exception as exc:
+ logger.warning("Agentic loop broadcast failed: %s", exc)
logger.debug("Agentic loop: WS broadcast failed for %s", event)
diff --git a/src/timmy/backends.py b/src/timmy/backends.py
index 7c8f619..cf1ba8b 100644
--- a/src/timmy/backends.py
+++ b/src/timmy/backends.py
@@ -414,7 +414,8 @@ def grok_available() -> bool:
from config import settings
return settings.grok_enabled and bool(settings.xai_api_key)
- except Exception:
+ except Exception as exc:
+ logger.warning("Backend check failed (grok_available): %s", exc)
return False
@@ -566,5 +567,6 @@ def claude_available() -> bool:
from config import settings
return bool(settings.anthropic_api_key)
- except Exception:
+ except Exception as exc:
+ logger.warning("Backend check failed (claude_available): %s", exc)
return False
diff --git a/src/timmy/cli.py b/src/timmy/cli.py
index 2d86c3e..b8f8598 100644
--- a/src/timmy/cli.py
+++ b/src/timmy/cli.py
@@ -259,7 +259,8 @@ def interview(
from timmy.mcp_tools import close_mcp_sessions
loop.run_until_complete(close_mcp_sessions())
- except Exception:
+ except Exception as exc:
+ logger.warning("MCP session close failed: %s", exc)
pass
loop.close()
diff --git a/src/timmy/loop_qa.py b/src/timmy/loop_qa.py
index 0b58cc2..a667333 100644
--- a/src/timmy/loop_qa.py
+++ b/src/timmy/loop_qa.py
@@ -262,7 +262,8 @@ def capture_error(exc, **kwargs):
from infrastructure.error_capture import capture_error as _capture
return _capture(exc, **kwargs)
- except Exception:
+ except Exception as capture_exc:
+ logger.debug("Failed to capture error: %s", capture_exc)
logger.debug("Failed to capture error", exc_info=True)
diff --git a/src/timmy/memory/vector_store.py b/src/timmy/memory/vector_store.py
index 925a249..37f951c 100644
--- a/src/timmy/memory/vector_store.py
+++ b/src/timmy/memory/vector_store.py
@@ -5,11 +5,14 @@ to retrieve relevant context from conversation history.
"""
import json
+import logging
import sqlite3
import uuid
from dataclasses import dataclass, field
from datetime import UTC, datetime
+logger = logging.getLogger(__name__)
+
def _check_embedding_model() -> bool | None:
"""Check if the canonical embedding model is available."""
@@ -18,7 +21,8 @@ def _check_embedding_model() -> bool | None:
model = _get_embedding_model()
return model is not None and model is not False
- except Exception:
+ except Exception as exc:
+ logger.debug("Embedding model check failed: %s", exc)
return None
diff --git a/src/timmy/thinking.py b/src/timmy/thinking.py
index 591c178..d934803 100644
--- a/src/timmy/thinking.py
+++ b/src/timmy/thinking.py
@@ -177,7 +177,8 @@ class ThinkingEngine:
latest = self.get_recent_thoughts(limit=1)
if latest:
self._last_thought_id = latest[0].id
- except Exception:
+ except Exception as exc:
+ logger.debug("Failed to load recent thought: %s", exc)
pass # Fresh start if DB doesn't exist yet
async def think_once(self, prompt: str | None = None) -> Thought | None:
@@ -578,7 +579,8 @@ class ThinkingEngine:
).fetchone()["c"]
conn.close()
parts.append(f"Thoughts today: {count}")
- except Exception:
+ except Exception as exc:
+ logger.debug("Thought count query failed: %s", exc)
pass
# Recent chat activity (in-memory, no I/O)
@@ -592,7 +594,8 @@ class ThinkingEngine:
parts.append(f'Last chat ({last.role}): "{last.content[:80]}"')
else:
parts.append("No chat messages this session")
- except Exception:
+ except Exception as exc:
+ logger.debug("Chat activity query failed: %s", exc)
pass
# Task queue (lightweight DB query)
@@ -609,7 +612,8 @@ class ThinkingEngine:
f"Tasks: {running} running, {pending} pending, "
f"{done} completed, {failed} failed"
)
- except Exception:
+ except Exception as exc:
+ logger.debug("Task queue query failed: %s", exc)
pass
return "\n".join(parts) if parts else ""
diff --git a/src/timmy/tools.py b/src/timmy/tools.py
index 08a8d24..e9d53ca 100644
--- a/src/timmy/tools.py
+++ b/src/timmy/tools.py
@@ -440,7 +440,8 @@ def consult_grok(query: str) -> str:
tool_name="consult_grok",
success=True,
)
- except Exception:
+ except Exception as exc:
+ logger.warning("Tool execution failed (consult_grok logging): %s", exc)
pass
# Generate Lightning invoice for monetization (unless free mode)
@@ -453,7 +454,8 @@ def consult_grok(query: str) -> str:
sats = min(settings.grok_max_sats_per_query, 100)
inv = ln.create_invoice(sats, f"Grok query: {query[:50]}")
invoice_info = f"\n[Lightning invoice: {sats} sats — {inv.payment_request[:40]}...]"
- except Exception:
+ except Exception as exc:
+ logger.warning("Tool execution failed (Lightning invoice): %s", exc)
pass
result = backend.run(query)
@@ -512,7 +514,8 @@ def create_full_toolkit(base_dir: str | Path | None = None):
if grok_available():
toolkit.register(consult_grok, name="consult_grok")
logger.info("Grok consultation tool registered")
- except Exception:
+ except Exception as exc:
+ logger.warning("Tool execution failed (Grok registration): %s", exc)
logger.debug("Grok tool not available")
# Memory search, write, and forget — persistent recall across all channels
@@ -523,7 +526,8 @@ def create_full_toolkit(base_dir: str | Path | None = None):
toolkit.register(memory_write, name="memory_write")
toolkit.register(memory_read, name="memory_read")
toolkit.register(memory_forget, name="memory_forget")
- except Exception:
+ except Exception as exc:
+ logger.warning("Tool execution failed (Memory tools registration): %s", exc)
logger.debug("Memory tools not available")
# Agentic loop — background multi-step task execution
@@ -569,7 +573,8 @@ def create_full_toolkit(base_dir: str | Path | None = None):
)
toolkit.register(plan_and_execute, name="plan_and_execute")
- except Exception:
+ except Exception as exc:
+ logger.warning("Tool execution failed (plan_and_execute registration): %s", exc)
logger.debug("plan_and_execute tool not available")
# System introspection - query runtime environment (sovereign self-knowledge)
@@ -579,7 +584,8 @@ def create_full_toolkit(base_dir: str | Path | None = None):
toolkit.register(get_system_info, name="get_system_info")
toolkit.register(check_ollama_health, name="check_ollama_health")
toolkit.register(get_memory_status, name="get_memory_status")
- except Exception:
+ except Exception as exc:
+ logger.warning("Tool execution failed (Introspection tools registration): %s", exc)
logger.debug("Introspection tools not available")
# Inter-agent delegation - dispatch tasks to swarm agents
@@ -588,7 +594,8 @@ def create_full_toolkit(base_dir: str | Path | None = None):
toolkit.register(delegate_task, name="delegate_task")
toolkit.register(list_swarm_agents, name="list_swarm_agents")
- except Exception:
+ except Exception as exc:
+ logger.warning("Tool execution failed (Delegation tools registration): %s", exc)
logger.debug("Delegation tools not available")
# Gitea issue management is now provided by the gitea-mcp server
diff --git a/src/timmy/tools_intro/__init__.py b/src/timmy/tools_intro/__init__.py
index c2fb742..9f75bec 100644
--- a/src/timmy/tools_intro/__init__.py
+++ b/src/timmy/tools_intro/__init__.py
@@ -89,7 +89,8 @@ def _get_ollama_model() -> str:
name = model.get("name", "")
if name == configured or name == f"{configured}:latest":
return configured
- except Exception:
+ except Exception as exc:
+ logger.debug("Model validation failed: %s", exc)
pass
# Fallback to configured model
@@ -186,7 +187,8 @@ def get_memory_status() -> dict[str, Any]:
tier3_info["available"] = True
tier3_info["vector_count"] = count[0] if count else 0
conn.close()
- except Exception:
+ except Exception as exc:
+ logger.debug("Memory status query failed: %s", exc)
pass
# Self-coding journal stats
@@ -212,7 +214,8 @@ def get_memory_status() -> dict[str, Any]:
"success_rate": round(counts.get("success", 0) / total, 2) if total else 0,
}
conn.close()
- except Exception:
+ except Exception as exc:
+ logger.debug("Journal stats query failed: %s", exc)
pass
return {
@@ -303,7 +306,8 @@ def get_live_system_status() -> dict[str, Any]:
uptime = (datetime.now(UTC) - _START_TIME).total_seconds()
result["uptime_seconds"] = int(uptime)
- except Exception:
+ except Exception as exc:
+ logger.debug("Uptime calculation failed: %s", exc)
result["uptime_seconds"] = None
# Discord status
@@ -311,7 +315,8 @@ def get_live_system_status() -> dict[str, Any]:
from integrations.chat_bridge.vendors.discord import discord_bot
result["discord"] = {"state": discord_bot.state.name}
- except Exception:
+ except Exception as exc:
+ logger.debug("Discord status check failed: %s", exc)
result["discord"] = {"state": "unknown"}
result["timestamp"] = datetime.now(UTC).isoformat()
diff --git a/src/timmy/voice_loop.py b/src/timmy/voice_loop.py
index d802402..8375fca 100644
--- a/src/timmy/voice_loop.py
+++ b/src/timmy/voice_loop.py
@@ -465,14 +465,16 @@ class VoiceLoop:
try:
self._loop.run_until_complete(self._loop.shutdown_asyncgens())
- except Exception:
+ except Exception as exc:
+ logger.debug("Shutdown asyncgens failed: %s", exc)
pass
with warnings.catch_warnings():
warnings.simplefilter("ignore", RuntimeWarning)
try:
self._loop.close()
- except Exception:
+ except Exception as exc:
+ logger.debug("Loop close failed: %s", exc)
pass
self._loop = None
diff --git a/src/timmy_serve/voice_tts.py b/src/timmy_serve/voice_tts.py
index 3ffbe2f..251b97f 100644
--- a/src/timmy_serve/voice_tts.py
+++ b/src/timmy_serve/voice_tts.py
@@ -87,7 +87,8 @@ class VoiceTTS:
{"id": v.id, "name": v.name, "languages": getattr(v, "languages", [])}
for v in voices
]
- except Exception:
+ except Exception as exc:
+ logger.debug("Voice list retrieval failed: %s", exc)
return []
def set_voice(self, voice_id: str) -> None: