fix: add debug log file locking, improve error logging, validate cloud API key

- Add portalocker file locking to debug_log() to prevent interleaved entries
- Add exc_info=True to curator _call_llm error logging for stack traces
- Add debug log message on JSON parse fallback in _parse_json_response
- Warn when cloud is enabled but API key env var is not set

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude Code
2026-04-01 16:15:56 -05:00
parent cbe12f0ebd
commit 6154e7974e
3 changed files with 13 additions and 2 deletions

View File

@@ -113,6 +113,13 @@ class Config:
models=cloud_data.get("models", {}) models=cloud_data.get("models", {})
) )
if config.cloud.enabled and not config.cloud.api_key:
import logging
logging.getLogger(__name__).warning(
"Cloud is enabled but API key env var '%s' is not set",
config.cloud.api_key_env
)
return config return config
config = Config.load() config = Config.load()

View File

@@ -212,7 +212,7 @@ Remember: Respond with ONLY valid JSON. No markdown, no explanations, just the J
result = response.json() result = response.json()
return result.get("response", "") return result.get("response", "")
except Exception as e: except Exception as e:
logger.error(f"Failed to call LLM: {e}") logger.error(f"LLM call failed: {e}", exc_info=True)
return "" return ""
def _parse_json_response(self, response: str) -> Optional[Dict]: def _parse_json_response(self, response: str) -> Optional[Dict]:
@@ -223,6 +223,7 @@ Remember: Respond with ONLY valid JSON. No markdown, no explanations, just the J
try: try:
return json.loads(response) return json.loads(response)
except json.JSONDecodeError: except json.JSONDecodeError:
logger.debug("Direct JSON parse failed, trying brace extraction")
pass pass
try: try:

View File

@@ -6,6 +6,7 @@ import json
import re import re
import logging import logging
import os import os
import portalocker
from pathlib import Path from pathlib import Path
from .config import config from .config import config
from .singleton import get_qdrant_service from .singleton import get_qdrant_service
@@ -66,7 +67,9 @@ def debug_log(category: str, message: str, data: dict = None):
entry["data"] = data entry["data"] = data
with open(log_path, "a") as f: with open(log_path, "a") as f:
portalocker.lock(f, portalocker.LOCK_EX)
f.write(json.dumps(entry) + "\n") f.write(json.dumps(entry) + "\n")
portalocker.unlock(f)
async def handle_chat_non_streaming(body: dict): async def handle_chat_non_streaming(body: dict):