mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 13:02:59 +00:00
fix: catch ConfigError in display preview generator (#288)
* fix: catch ConfigError in display preview generator PR #282 narrowed bare except blocks but missed ConfigError from config_manager.load_config(), which wraps FileNotFoundError, JSONDecodeError, and OSError. Without this, a corrupt or missing config crashes the display preview SSE endpoint instead of falling back to 128x64 defaults. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(security): comprehensive error handling cleanup - Remove all traceback.format_exc() from client responses (33 remaining instances) - Sanitize str(e) from client-facing messages, replacing with generic error messages - Replace ~65 bare print() calls with structured logger.exception/error/warning/info/debug - Remove ~35 redundant inline `import traceback` and `import logging` statements - Convert logging.error/warning calls to use module-level named logger - Fix WiFi endpoints that created redundant inline logger instances - Add logger.exception() at all WebInterfaceError.from_exception() call sites - Fix from_exception() in errors.py to use safe messages instead of raw str(exception) - Apply consistent [Tag] prefixes to all logger calls for production triage Only safe, user-input-derived str(e) kept: json.JSONDecodeError handlers (400 responses). Subprocess template print(stdout) calls preserved (not error logging). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(security): correct error inference, remove debug log leak, consolidate config handlers - _infer_error_code: map Config* exceptions to CONFIG_LOAD_FAILED (ConfigError is only raised by load_config(), so CONFIG_SAVE_FAILED produced wrong safe message and wrong suggested_fixes) - Remove leftover DEBUG logs in save_main_config that dumped full request body and all HTTP headers (Authorization, Cookie, etc.) - Replace dead FileNotFoundError/JSONDecodeError/IOError handlers in get_dim_schedule_config with single ConfigError catch (load_config already wraps these into ConfigError) - Remove redundant local `from src.exceptions import ConfigError` imports now covered by top-level import - Strip str(e) from client-facing error messages in dim schedule handler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(security): fix plugin update logging and config validation leak - update_plugin: change logger.exception to logger.error in non-except branch (logger.exception outside an except block logs useless "NoneType: None" traceback) - update_plugin: remove duplicate logger.exception call in except block (was logging the same failure twice) - save_plugin_config validation: stop logging full plugin_config dict (can contain API keys, passwords, tokens) and raw form_data values; log only keys and validation errors instead Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Chuck <chuck@example.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -214,19 +214,47 @@ class WebInterfaceError:
|
||||
|
||||
return cls(
|
||||
error_code=error_code,
|
||||
message=str(exception),
|
||||
message=cls._safe_message(error_code),
|
||||
details=cls._get_exception_details(exception),
|
||||
context=error_context,
|
||||
original_error=exception
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _safe_message(cls, error_code: ErrorCode) -> str:
|
||||
"""Get a safe, user-facing message for an error code."""
|
||||
messages = {
|
||||
ErrorCode.CONFIG_SAVE_FAILED: "Failed to save configuration",
|
||||
ErrorCode.CONFIG_LOAD_FAILED: "Failed to load configuration",
|
||||
ErrorCode.CONFIG_VALIDATION_FAILED: "Configuration validation failed",
|
||||
ErrorCode.CONFIG_ROLLBACK_FAILED: "Failed to rollback configuration",
|
||||
ErrorCode.PLUGIN_NOT_FOUND: "Plugin not found",
|
||||
ErrorCode.PLUGIN_INSTALL_FAILED: "Failed to install plugin",
|
||||
ErrorCode.PLUGIN_UPDATE_FAILED: "Failed to update plugin",
|
||||
ErrorCode.PLUGIN_UNINSTALL_FAILED: "Failed to uninstall plugin",
|
||||
ErrorCode.PLUGIN_LOAD_FAILED: "Failed to load plugin",
|
||||
ErrorCode.PLUGIN_OPERATION_CONFLICT: "A plugin operation is already in progress",
|
||||
ErrorCode.VALIDATION_ERROR: "Validation error",
|
||||
ErrorCode.SCHEMA_VALIDATION_FAILED: "Schema validation failed",
|
||||
ErrorCode.INVALID_INPUT: "Invalid input",
|
||||
ErrorCode.NETWORK_ERROR: "Network error",
|
||||
ErrorCode.API_ERROR: "API error",
|
||||
ErrorCode.TIMEOUT: "Operation timed out",
|
||||
ErrorCode.PERMISSION_DENIED: "Permission denied",
|
||||
ErrorCode.FILE_PERMISSION_ERROR: "File permission error",
|
||||
ErrorCode.SYSTEM_ERROR: "A system error occurred",
|
||||
ErrorCode.SERVICE_UNAVAILABLE: "Service unavailable",
|
||||
ErrorCode.UNKNOWN_ERROR: "An unexpected error occurred",
|
||||
}
|
||||
return messages.get(error_code, "An unexpected error occurred")
|
||||
|
||||
@classmethod
|
||||
def _infer_error_code(cls, exception: Exception) -> ErrorCode:
|
||||
"""Infer error code from exception type."""
|
||||
exception_name = type(exception).__name__
|
||||
|
||||
if "Config" in exception_name:
|
||||
return ErrorCode.CONFIG_SAVE_FAILED
|
||||
return ErrorCode.CONFIG_LOAD_FAILED
|
||||
elif "Plugin" in exception_name:
|
||||
return ErrorCode.PLUGIN_LOAD_FAILED
|
||||
elif "Permission" in exception_name or "Access" in exception_name:
|
||||
|
||||
@@ -11,6 +11,7 @@ from datetime import datetime, timedelta
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
from src.config_manager import ConfigManager
|
||||
from src.exceptions import ConfigError
|
||||
from src.plugin_system.plugin_manager import PluginManager
|
||||
from src.plugin_system.store_manager import PluginStoreManager
|
||||
from src.plugin_system.saved_repositories import SavedRepositoriesManager
|
||||
@@ -492,7 +493,7 @@ def display_preview_generator():
|
||||
parallel = main_config.get('display', {}).get('hardware', {}).get('parallel', 1)
|
||||
width = cols * chain_length
|
||||
height = rows * parallel
|
||||
except (KeyError, TypeError, ValueError):
|
||||
except (KeyError, TypeError, ValueError, ConfigError):
|
||||
width = 128
|
||||
height = 64
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user