fix: add logging to silent except Exception handlers across codebase
Some checks failed
Tests / lint (pull_request) Has been cancelled
Tests / test (pull_request) Has been cancelled

Add logger.exception() calls to 20 silent except Exception handlers
that were swallowing errors without any logging, making production
debugging extremely difficult.

Files fixed:
- timmy/loop_qa.py (6 handlers in probe functions + orchestrator)
- timmy/backends.py (2 handlers in health_check methods)
- timmy/tools_delegation/__init__.py (1 handler in _run_kimi)
- timmy/tools_intro/__init__.py (4 handlers in introspection tools)
- dashboard/middleware/request_logging.py (1 handler upgraded debug→warning)
- dashboard/routes/health.py (1 handler in _check_sqlite)
- dashboard/routes/grok.py (2 handlers in query and stats)
- dashboard/routes/voice.py (1 handler in tts_speak)
- dashboard/routes/db_explorer.py (2 handlers in _query_database)

No control flow changes — only added logging before existing returns.

Fixes #646

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
kimi
2026-03-20 23:48:33 -04:00
parent c9445e3056
commit c97ac19b7b
9 changed files with 20 additions and 1 deletions

View File

@@ -116,7 +116,7 @@ class RequestLoggingMiddleware(BaseHTTPMiddleware):
},
)
except Exception as exc:
logger.debug("Escalation logging error: %s", exc)
logger.warning("Escalation logging error: %s", exc)
pass # never let escalation break the request
# Re-raise the exception

View File

@@ -75,6 +75,7 @@ def _query_database(db_path: str) -> dict:
"truncated": count > MAX_ROWS,
}
except Exception as exc:
logger.exception("Failed to query table %s", table_name)
result["tables"][table_name] = {
"error": str(exc),
"columns": [],
@@ -83,6 +84,7 @@ def _query_database(db_path: str) -> dict:
"truncated": False,
}
except Exception as exc:
logger.exception("Failed to query database %s", db_path)
result["error"] = str(exc)
return result

View File

@@ -135,6 +135,7 @@ def _run_grok_query(message: str) -> dict:
result = backend.run(message)
return {"response": f"**[Grok]{invoice_note}:** {result.content}", "error": None}
except Exception as exc:
logger.exception("Grok query failed")
return {"response": None, "error": f"Grok error: {exc}"}
@@ -193,6 +194,7 @@ async def grok_stats():
"model": settings.grok_default_model,
}
except Exception as exc:
logger.exception("Failed to load Grok stats")
return {"error": str(exc)}

View File

@@ -148,6 +148,7 @@ def _check_sqlite() -> DependencyStatus:
details={"path": str(db_path)},
)
except Exception as exc:
logger.exception("SQLite health check failed")
return DependencyStatus(
name="SQLite Database",
status="unavailable",

View File

@@ -59,6 +59,7 @@ async def tts_speak(text: str = Form(...)):
voice_tts.speak(text)
return {"spoken": True, "text": text}
except Exception as exc:
logger.exception("TTS speak failed")
return {"spoken": False, "reason": str(exc)}

View File

@@ -264,6 +264,7 @@ class GrokBackend:
},
}
except Exception as exc:
logger.exception("Grok health check failed")
return {
"ok": False,
"error": str(exc),
@@ -430,6 +431,7 @@ class ClaudeBackend:
)
return {"ok": True, "error": None, "backend": "claude", "model": self._model}
except Exception as exc:
logger.exception("Claude health check failed")
return {"ok": False, "error": str(exc), "backend": "claude", "model": self._model}
# ── Private helpers ───────────────────────────────────────────────────

View File

@@ -97,6 +97,7 @@ async def probe_tool_use() -> dict:
"error_type": "empty_result",
}
except Exception as exc:
logger.exception("Tool use probe failed")
return {
"success": False,
"capability": cap,
@@ -129,6 +130,7 @@ async def probe_multistep_planning() -> dict:
"error_type": "verification_failed",
}
except Exception as exc:
logger.exception("Multistep planning probe failed")
return {
"success": False,
"capability": cap,
@@ -151,6 +153,7 @@ async def probe_memory_write() -> dict:
"error_type": None,
}
except Exception as exc:
logger.exception("Memory write probe failed")
return {
"success": False,
"capability": cap,
@@ -179,6 +182,7 @@ async def probe_memory_read() -> dict:
"error_type": "empty_result",
}
except Exception as exc:
logger.exception("Memory read probe failed")
return {
"success": False,
"capability": cap,
@@ -214,6 +218,7 @@ async def probe_self_coding() -> dict:
"error_type": "verification_failed",
}
except Exception as exc:
logger.exception("Self-coding probe failed")
return {
"success": False,
"capability": cap,
@@ -325,6 +330,7 @@ class LoopQAOrchestrator:
result = await probe_fn()
except Exception as exc:
# Probe itself crashed — record failure and report
logger.exception("Loop QA probe %s crashed", cap.value)
capture_error(exc, source="loop_qa", context={"capability": cap.value})
result = {
"success": False,

View File

@@ -139,6 +139,7 @@ def _run_kimi(cmd: list[str], workdir: str) -> dict[str, Any]:
"error": "Kimi timed out after 300s. Task may be too broad — try breaking it into smaller pieces.",
}
except Exception as exc:
logger.exception("Failed to run Kimi subprocess")
return {
"success": False,
"error": f"Failed to run Kimi: {exc}",

View File

@@ -122,6 +122,7 @@ def check_ollama_health() -> dict[str, Any]:
models = response.json().get("models", [])
result["available_models"] = [m.get("name", "") for m in models]
except Exception as e:
logger.exception("Ollama health check failed")
result["error"] = str(e)
return result
@@ -289,6 +290,7 @@ def get_live_system_status() -> dict[str, Any]:
try:
result["system"] = get_system_info()
except Exception as exc:
logger.exception("Failed to get system info")
result["system"] = {"error": str(exc)}
# Task queue
@@ -301,6 +303,7 @@ def get_live_system_status() -> dict[str, Any]:
try:
result["memory"] = get_memory_status()
except Exception as exc:
logger.exception("Failed to get memory status")
result["memory"] = {"error": str(exc)}
# Uptime
@@ -406,4 +409,5 @@ def run_self_tests(scope: str = "fast", _repo_root: str | None = None) -> dict[s
except subprocess.TimeoutExpired:
return {"success": False, "error": "Test run timed out (120s limit)"}
except Exception as exc:
logger.exception("Self-test run failed")
return {"success": False, "error": str(exc)}