mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-11 13:23:00 +00:00
fix(starlark): critical bug fixes and code quality improvements
Critical fixes: - Fix stack overflow in safeLocalStorage (was recursively calling itself) - Fix duplicate event listeners on Starlark grid (added sentinel check) - Fix JSON validation to fail fast on malformed data instead of silently passing Error handling improvements: - Narrow exception catches to specific types (OSError, json.JSONDecodeError, ValueError) - Use logger.exception() with exc_info=True for better stack traces - Replace generic "except Exception" with specific exception types Logging improvements: - Add "[Starlark Pixlet]" context tags to pixlet_renderer logs - Redact sensitive config values from debug logs (API keys, etc.) - Add file_path context to schema parsing warnings Documentation: - Fix markdown lint issues (add language tags to code blocks) - Fix time unit spacing: "(5min)" -> "(5 min)" Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -63,7 +63,7 @@ class StarlarkApp:
|
||||
try:
|
||||
with open(self.config_file, 'r') as f:
|
||||
return json.load(f)
|
||||
except Exception as e:
|
||||
except (OSError, json.JSONDecodeError) as e:
|
||||
logger.warning(f"Could not load config for {self.app_id}: {e}")
|
||||
return {}
|
||||
|
||||
@@ -73,7 +73,7 @@ class StarlarkApp:
|
||||
try:
|
||||
with open(self.schema_file, 'r') as f:
|
||||
return json.load(f)
|
||||
except Exception as e:
|
||||
except (OSError, json.JSONDecodeError) as e:
|
||||
logger.warning(f"Could not load schema for {self.app_id}: {e}")
|
||||
return None
|
||||
|
||||
@@ -118,6 +118,11 @@ class StarlarkApp:
|
||||
if isinstance(value, str) and value.strip().startswith('{'):
|
||||
try:
|
||||
loc = json.loads(value)
|
||||
except json.JSONDecodeError as e:
|
||||
return f"Invalid JSON for key {key}: {e}"
|
||||
|
||||
# Validate lat/lng if present
|
||||
try:
|
||||
if 'lat' in loc:
|
||||
lat = float(loc['lat'])
|
||||
if not -90 <= lat <= 90:
|
||||
@@ -126,9 +131,8 @@ class StarlarkApp:
|
||||
lng = float(loc['lng'])
|
||||
if not -180 <= lng <= 180:
|
||||
return f"Longitude {lng} out of range [-180, 180] for key {key}"
|
||||
except (json.JSONDecodeError, ValueError, KeyError) as e:
|
||||
# Not a location field, that's fine
|
||||
pass
|
||||
except ValueError as e:
|
||||
return f"Invalid numeric value for {key}: {e}"
|
||||
|
||||
return None
|
||||
|
||||
@@ -584,8 +588,8 @@ class StarlarkAppsPlugin(BasePlugin):
|
||||
fcntl.flock(lock_fd, fcntl.LOCK_UN)
|
||||
os.close(lock_fd)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error saving manifest: {e}")
|
||||
except (OSError, IOError, json.JSONDecodeError, ValueError) as e:
|
||||
self.logger.exception("Error saving manifest while writing manifest file", exc_info=True)
|
||||
# Clean up temp file if it exists
|
||||
if temp_file is not None and temp_file.exists():
|
||||
try:
|
||||
@@ -651,8 +655,8 @@ class StarlarkAppsPlugin(BasePlugin):
|
||||
fcntl.flock(lock_fd, fcntl.LOCK_UN)
|
||||
os.close(lock_fd)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error updating manifest: {e}")
|
||||
except (OSError, IOError, json.JSONDecodeError, ValueError) as e:
|
||||
self.logger.exception("Error updating manifest during read-modify-write cycle", exc_info=True)
|
||||
# Clean up temp file if it exists
|
||||
if temp_file is not None and temp_file.exists():
|
||||
try:
|
||||
|
||||
@@ -41,9 +41,9 @@ class PixletRenderer:
|
||||
self.pixlet_binary = self._find_pixlet_binary(pixlet_path)
|
||||
|
||||
if self.pixlet_binary:
|
||||
logger.info(f"Pixlet renderer initialized with binary: {self.pixlet_binary}")
|
||||
logger.info(f"[Starlark Pixlet] Pixlet renderer initialized with binary: {self.pixlet_binary}")
|
||||
else:
|
||||
logger.warning("Pixlet binary not found - rendering will fail")
|
||||
logger.warning("[Starlark Pixlet] Pixlet binary not found - rendering will fail")
|
||||
|
||||
def _find_pixlet_binary(self, explicit_path: Optional[str] = None) -> Optional[str]:
|
||||
"""
|
||||
@@ -280,7 +280,13 @@ class PixletRenderer:
|
||||
"-m", str(magnify)
|
||||
])
|
||||
|
||||
logger.debug(f"Executing Pixlet: {' '.join(cmd)}")
|
||||
# Build sanitized command for logging (redact sensitive values)
|
||||
sanitized_cmd = [self.pixlet_binary, "render", star_file]
|
||||
if config:
|
||||
config_keys = list(config.keys())
|
||||
sanitized_cmd.append(f"[{len(config_keys)} config entries: {', '.join(config_keys)}]")
|
||||
sanitized_cmd.extend(["-o", output_path, "-m", str(magnify)])
|
||||
logger.debug(f"Executing Pixlet: {' '.join(sanitized_cmd)}")
|
||||
|
||||
# Execute rendering
|
||||
safe_cwd = self._get_safe_working_directory(star_file)
|
||||
@@ -373,6 +379,7 @@ class PixletRenderer:
|
||||
# Extract get_schema() function body
|
||||
schema_body = self._extract_get_schema_body(content)
|
||||
if not schema_body:
|
||||
logger.debug(f"No get_schema() function found in {file_path}")
|
||||
return None
|
||||
|
||||
# Extract version
|
||||
@@ -397,6 +404,7 @@ class PixletRenderer:
|
||||
|
||||
if bracket_count != 0:
|
||||
# Unmatched brackets
|
||||
logger.warning(f"Unmatched brackets in schema fields for {file_path}")
|
||||
return {"version": version, "schema": []}
|
||||
|
||||
fields_text = schema_body[fields_start_match.end():i-1]
|
||||
|
||||
Reference in New Issue
Block a user