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:
Chuck
2026-02-19 21:32:45 -05:00
parent 6a60a57421
commit 36da426c29
4 changed files with 48 additions and 33 deletions

View File

@@ -4,7 +4,7 @@ const safeLocalStorage = {
getItem(key) {
try {
if (typeof localStorage !== 'undefined') {
return safeLocalStorage.getItem(key);
return localStorage.getItem(key);
}
} catch (e) {
console.warn(`safeLocalStorage.getItem failed for key "${key}":`, e.message);
@@ -14,7 +14,7 @@ const safeLocalStorage = {
setItem(key, value) {
try {
if (typeof localStorage !== 'undefined') {
safeLocalStorage.setItem(key, value);
localStorage.setItem(key, value);
return true;
}
} catch (e) {
@@ -7924,24 +7924,27 @@ setTimeout(function() {
</div>`;
}).join('');
// Add delegated event listeners for install and view buttons
grid.addEventListener('click', function(e) {
const button = e.target.closest('button[data-action]');
if (!button) return;
// Add delegated event listener only once (prevent duplicate handlers)
if (!grid.dataset.starlarkHandlerAttached) {
grid.addEventListener('click', function handleStarlarkGridClick(e) {
const button = e.target.closest('button[data-action]');
if (!button) return;
const card = button.closest('.plugin-card');
if (!card) return;
const card = button.closest('.plugin-card');
if (!card) return;
const appId = card.dataset.appId;
if (!appId) return;
const appId = card.dataset.appId;
if (!appId) return;
const action = button.dataset.action;
if (action === 'install') {
window.installStarlarkApp(appId);
} else if (action === 'view') {
window.open('https://github.com/tronbyt/apps/tree/main/apps/' + encodeURIComponent(appId), '_blank');
}
});
const action = button.dataset.action;
if (action === 'install') {
window.installStarlarkApp(appId);
} else if (action === 'view') {
window.open('https://github.com/tronbyt/apps/tree/main/apps/' + encodeURIComponent(appId), '_blank');
}
});
grid.dataset.starlarkHandlerAttached = 'true';
}
}
// ── Filter UI Updates ───────────────────────────────────────────────────