mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-05 01:50:27 +08:00
fix(config): log configuration loading errors instead of silently ignoring
Replaces bare exception handler in load_settings() with logging.warning() to help users debug configuration file issues (syntax errors, permissions). Maintains backward compatibility - errors do not break initialization. Solution-ID: SOL-1735385400001 Issue-ID: ISS-1766921318981-1 Task-ID: T1
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from dataclasses import dataclass, field
|
||||
from functools import cached_property
|
||||
@@ -18,6 +19,8 @@ WORKSPACE_DIR_NAME = ".codexlens"
|
||||
# Settings file name
|
||||
SETTINGS_FILE_NAME = "settings.json"
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _default_global_dir() -> Path:
|
||||
"""Get global CodexLens data directory."""
|
||||
@@ -200,7 +203,15 @@ class Config:
|
||||
# Load embedding settings
|
||||
embedding = settings.get("embedding", {})
|
||||
if "backend" in embedding:
|
||||
self.embedding_backend = embedding["backend"]
|
||||
backend = embedding["backend"]
|
||||
if backend in {"fastembed", "litellm"}:
|
||||
self.embedding_backend = backend
|
||||
else:
|
||||
log.warning(
|
||||
"Invalid embedding backend in %s: %r (expected 'fastembed' or 'litellm')",
|
||||
self.settings_path,
|
||||
backend,
|
||||
)
|
||||
if "model" in embedding:
|
||||
self.embedding_model = embedding["model"]
|
||||
if "use_gpu" in embedding:
|
||||
@@ -224,8 +235,13 @@ class Config:
|
||||
self.llm_timeout_ms = llm["timeout_ms"]
|
||||
if "batch_size" in llm:
|
||||
self.llm_batch_size = llm["batch_size"]
|
||||
except Exception:
|
||||
pass # Silently ignore errors
|
||||
except Exception as exc:
|
||||
log.warning(
|
||||
"Failed to load settings from %s (%s): %s",
|
||||
self.settings_path,
|
||||
type(exc).__name__,
|
||||
exc,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def load(cls) -> "Config":
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
"""Tests for CodexLens configuration system."""
|
||||
|
||||
import builtins
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
@@ -224,6 +227,99 @@ class TestConfig:
|
||||
del os.environ["CODEXLENS_DATA_DIR"]
|
||||
|
||||
|
||||
class TestConfigLoadSettings:
|
||||
"""Tests for Config.load_settings behavior and logging."""
|
||||
|
||||
def test_load_settings_logs_warning_on_malformed_json(self, caplog):
|
||||
"""Malformed JSON in settings file should trigger warning log."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
config = Config(data_dir=Path(tmpdir))
|
||||
config.settings_path.write_text("{", encoding="utf-8")
|
||||
|
||||
with caplog.at_level(logging.WARNING):
|
||||
config.load_settings()
|
||||
|
||||
records = [r for r in caplog.records if r.name == "codexlens.config"]
|
||||
assert any("Failed to load settings from" in r.message for r in records)
|
||||
assert any("JSONDecodeError" in r.message for r in records)
|
||||
assert any(str(config.settings_path) in r.message for r in records)
|
||||
|
||||
def test_load_settings_logs_warning_on_permission_error(self, monkeypatch, caplog):
|
||||
"""Permission errors opening settings file should trigger warning log."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
config = Config(data_dir=Path(tmpdir))
|
||||
config.settings_path.write_text("{}", encoding="utf-8")
|
||||
|
||||
real_open = builtins.open
|
||||
|
||||
def guarded_open(path, mode="r", *args, **kwargs):
|
||||
if Path(path) == config.settings_path and "r" in mode:
|
||||
raise PermissionError("Permission denied")
|
||||
return real_open(path, mode, *args, **kwargs)
|
||||
|
||||
monkeypatch.setattr(builtins, "open", guarded_open)
|
||||
|
||||
with caplog.at_level(logging.WARNING):
|
||||
config.load_settings()
|
||||
|
||||
records = [r for r in caplog.records if r.name == "codexlens.config"]
|
||||
assert any("Failed to load settings from" in r.message for r in records)
|
||||
assert any("PermissionError" in r.message for r in records)
|
||||
|
||||
def test_load_settings_loads_valid_settings_without_warning(self, caplog):
|
||||
"""Valid settings should load without warning logs."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
config = Config(data_dir=Path(tmpdir))
|
||||
config.settings_path.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"embedding": {
|
||||
"backend": "fastembed",
|
||||
"model": "multilingual",
|
||||
"use_gpu": False,
|
||||
},
|
||||
"llm": {
|
||||
"enabled": True,
|
||||
"tool": "gemini",
|
||||
"timeout_ms": 1234,
|
||||
"batch_size": 7,
|
||||
},
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
with caplog.at_level(logging.WARNING):
|
||||
config.load_settings()
|
||||
|
||||
records = [r for r in caplog.records if r.name == "codexlens.config"]
|
||||
assert not records
|
||||
assert config.embedding_backend == "fastembed"
|
||||
assert config.embedding_model == "multilingual"
|
||||
assert config.embedding_use_gpu is False
|
||||
assert config.llm_enabled is True
|
||||
assert config.llm_tool == "gemini"
|
||||
assert config.llm_timeout_ms == 1234
|
||||
assert config.llm_batch_size == 7
|
||||
|
||||
def test_load_settings_logs_warning_on_invalid_embedding_backend(self, caplog):
|
||||
"""Invalid embedding backend should trigger warning log and keep default."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
config = Config(data_dir=Path(tmpdir))
|
||||
default_backend = config.embedding_backend
|
||||
config.settings_path.write_text(
|
||||
json.dumps({"embedding": {"backend": "invalid-backend"}}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
with caplog.at_level(logging.WARNING):
|
||||
config.load_settings()
|
||||
|
||||
records = [r for r in caplog.records if r.name == "codexlens.config"]
|
||||
assert any("Invalid embedding backend in" in r.message for r in records)
|
||||
assert config.embedding_backend == default_backend
|
||||
|
||||
|
||||
class TestWorkspaceConfig:
|
||||
"""Tests for WorkspaceConfig class."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user