@@ -255,7 +256,7 @@
document.getElementById('event-deploy-failed').checked = config.events?.deploymentFailed !== false;
}
} catch (error) {
- console.error('Failed to load notification config:', error);
+ errorHandler.logError('[Notifications] Load Config', error, { function: 'loadConfig' });
}
}
@@ -289,7 +290,7 @@
container.innerHTML = '
No notifications yet
';
}
} catch (error) {
- console.error('Failed to load notification history:', error);
+ errorHandler.logError('[Notifications] Load History', error, { function: 'loadHistory' });
}
}
diff --git a/status/js/onboarding.js b/status/js/onboarding.js
index 9ff4d8b..6a793bd 100644
--- a/status/js/onboarding.js
+++ b/status/js/onboarding.js
@@ -89,11 +89,8 @@
debug('[Onboarding] System initialized successfully');
} catch (error) {
- console.error('[Onboarding] Initialization error:', error);
-
- // Use error handler if available
if (errorHandler) {
- errorHandler.logError('Initialization', error);
+ errorHandler.logError('[Onboarding] Initialization', error);
}
// Graceful degradation - don't break the dashboard
@@ -113,7 +110,9 @@
debug('[Onboarding] Starting tour via button click');
tourManager.restartTour();
} else {
- console.error('[Onboarding] Tour manager not initialized');
+ if (errorHandler) {
+ errorHandler.logError('[Onboarding] Tour Manager Not Initialized', new Error('Tour manager not initialized'));
+ }
alert('Tour is not available. Check browser console for errors.\n\nPossible issues:\n- Driver.js library failed to load\n- JavaScript errors during initialization');
}
};
@@ -163,7 +162,6 @@
setTimeout(attemptInit, 500);
} else {
// Max retries reached, show fallback
- console.error('[Onboarding] Driver.js failed to load after multiple attempts');
if (errorHandler) {
errorHandler.handleDriverLoadFailure();
} else {
diff --git a/status/js/progress-tracker.js b/status/js/progress-tracker.js
index 035790a..8982406 100644
--- a/status/js/progress-tracker.js
+++ b/status/js/progress-tracker.js
@@ -18,6 +18,8 @@
(function(window) {
'use strict';
+ const errorHandler = new ErrorHandler();
+
const debug = (...args) => {
if (window.DASHCADDY_DEBUG) { console.log(...args); }
};
@@ -72,7 +74,7 @@
const data = localStorage.getItem(this.storageKey);
return data ? JSON.parse(data) : null;
} catch (error) {
- console.error('[ProgressTracker] Error reading from storage:', error);
+ errorHandler.logError('[ProgressTracker] Read Storage', error, { function: '_getStorage' });
return null;
}
}
@@ -86,7 +88,7 @@
try {
localStorage.setItem(this.storageKey, JSON.stringify(state));
} catch (error) {
- console.error('[ProgressTracker] Error writing to storage:', error);
+ errorHandler.logError('[ProgressTracker] Write Storage', error, { function: '_setStorage' });
// Handle quota exceeded or storage unavailable
// Fall back to session storage or in-memory storage
this._handleStorageError(error);
@@ -104,7 +106,7 @@
sessionStorage.setItem(this.storageKey, JSON.stringify(this._getStorage()));
console.warn('[ProgressTracker] Falling back to session storage');
} catch (sessionError) {
- console.error('[ProgressTracker] Session storage also unavailable:', sessionError);
+ errorHandler.logError('[ProgressTracker] Session Storage Unavailable', sessionError, { function: '_handleStorageError' });
// Could implement in-memory fallback here if needed
}
}
@@ -190,7 +192,7 @@
body: JSON.stringify({ onboardingCompleted: true })
});
} catch (error) {
- console.error('[ProgressTracker] Failed to persist install onboarding state:', error);
+ errorHandler.logError('[ProgressTracker] Persist Install Onboarding', error, { function: 'markInstallOnboardingCompleted' });
}
}
diff --git a/status/js/service-credentials.js b/status/js/service-credentials.js
index e5ddb06..0186b74 100644
--- a/status/js/service-credentials.js
+++ b/status/js/service-credentials.js
@@ -1,5 +1,6 @@
// ===== SERVICE CREDENTIALS =====
(function() {
+ const errorHandler = new ErrorHandler();
injectModal('folder-browser-modal', `
📂 Browse for Media Folders
@@ -433,7 +434,7 @@
await loadServiceCreds(currentService);
} catch (e) {
- console.error('Failed to save credentials:', e);
+ errorHandler.logError('[ServiceCredentials] Save', e, { function: 'saveCredentials' });
showError('Failed to save: ' + (e.message || 'Unknown error'));
}
saveBtn.textContent = 'Save';
@@ -460,7 +461,7 @@
if (btn) btn.classList.remove('has-creds');
await loadServiceCreds(currentService);
} catch (e) {
- console.error('Failed to clear credentials:', e);
+ errorHandler.logError('[ServiceCredentials] Clear', e, { function: 'clearCredentials' });
showError('Failed to clear: ' + (e.message || 'Unknown error'));
}
});
diff --git a/status/js/setup-wizard.js b/status/js/setup-wizard.js
index 15a396d..c6dd957 100644
--- a/status/js/setup-wizard.js
+++ b/status/js/setup-wizard.js
@@ -1,4 +1,6 @@
// Shared timezone utility — used by setup wizard and settings modal
+const errorHandler = new ErrorHandler();
+
window.populateTimezoneSelect = function(selectEl, selectedTz) {
const timezones = Intl.supportedValuesOf('timeZone');
const detected = selectedTz || Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';
@@ -150,11 +152,11 @@ window.populateTimezoneSelect = function(selectEl, selectedTz) {
await response.json();
return true;
} else {
- console.error('Failed to save config to server:', response.status);
+ errorHandler.logError('[SetupWizard] Save Config', new Error(`Server returned ${response.status}`), { function: 'saveConfigToServer' });
return false;
}
} catch (error) {
- console.error('Error saving config to server:', error);
+ errorHandler.logError('[SetupWizard] Save Config', error, { function: 'saveConfigToServer' });
return false;
}
}
diff --git a/status/js/theme-adapter.js b/status/js/theme-adapter.js
index 3e45e63..b0afc40 100644
--- a/status/js/theme-adapter.js
+++ b/status/js/theme-adapter.js
@@ -7,6 +7,8 @@
(function(window) {
'use strict';
+ const errorHandler = new ErrorHandler();
+
const debug = (...args) => {
if (window.DASHCADDY_DEBUG) { console.log(...args); }
};
@@ -190,7 +192,7 @@
try {
callback(newTheme, oldTheme);
} catch (error) {
- console.error('[ThemeAdapter] Error in theme change callback:', error);
+ errorHandler.logError('[ThemeAdapter] Theme Change Callback', error, { function: '_notifyThemeChange' });
}
});
}
diff --git a/status/js/tooltip-definitions.js b/status/js/tooltip-definitions.js
index 0509499..215bd89 100644
--- a/status/js/tooltip-definitions.js
+++ b/status/js/tooltip-definitions.js
@@ -6,6 +6,8 @@
(function(window) {
'use strict';
+ const errorHandler = new ErrorHandler();
+
const debug = (...args) => {
if (window.DASHCADDY_DEBUG) { console.log(...args); }
};
@@ -151,7 +153,7 @@
`${e.tooltip}: ${e.errors.join(', ')}`
).join('\n');
- console.error('[TooltipDefinitions] Validation errors:', errorMessages);
+ errorHandler.logError('[TooltipDefinitions] Validation', errorMessages, { function: 'validateTooltip' });
throw new TooltipError(`Tooltip validation failed:\n${errorMessages}`);
}
}
@@ -493,7 +495,7 @@ function getActiveTooltips() {
try {
return tooltip.condition();
} catch (error) {
- console.error(`[TooltipDefinitions] Error evaluating condition for ${tooltip.id}:`, error);
+ errorHandler.logError('[TooltipDefinitions] Condition Eval', error, { function: 'evaluateCondition', tooltipId: tooltip.id });
return false;
}
}
diff --git a/status/js/totp-settings.js b/status/js/totp-settings.js
index c326177..b4e54e5 100644
--- a/status/js/totp-settings.js
+++ b/status/js/totp-settings.js
@@ -1,5 +1,6 @@
// ===== TOTP SETTINGS =====
(function() {
+ const errorHandler = new ErrorHandler();
injectModal('totp-settings-modal', `
Authentication Settings
@@ -185,7 +186,7 @@
document.getElementById('totp-setup-code').focus();
}
} catch (e) {
- console.error('TOTP setup failed:', e);
+ errorHandler.logError('[TOTP] Setup Failed', e, { function: 'setupTOTP' });
}
});
@@ -274,7 +275,7 @@
});
loadTotpSettings(); // Refresh modal + card (handles "never" disabling TOTP)
} catch (err) {
- console.error('Failed to update session duration:', err);
+ errorHandler.logError('[TOTP] Update Session Duration', err, { function: 'updateSessionDuration' });
}
});
@@ -290,7 +291,7 @@
const data = await res.json();
if (data.success) loadTotpSettings();
} catch (e) {
- console.error('Failed to disable TOTP:', e);
+ errorHandler.logError('[TOTP] Disable Failed', e, { function: 'disableTOTP' });
}
});
@@ -322,7 +323,7 @@
const active = data.config.enabled && data.config.isSetUp;
updateAuthCard(active, data.config.sessionDuration);
}
- } catch (e) { console.error('[AuthCard] Failed to update:', e); }
+ } catch (e) { errorHandler.logError('[TOTP] AuthCard Update', e, { function: 'authCardUpdate' }); }
})();
})();
diff --git a/status/js/tour-manager.js b/status/js/tour-manager.js
index d1b92a6..c145d7f 100644
--- a/status/js/tour-manager.js
+++ b/status/js/tour-manager.js
@@ -6,6 +6,8 @@
(function(window) {
'use strict';
+ const errorHandler = new ErrorHandler();
+
const debug = (...args) => {
if (window.DASHCADDY_DEBUG) { console.log(...args); }
};
@@ -30,7 +32,7 @@
const driverFactory = window.driver?.js?.driver || window.driver?.driver || window.driver;
if (typeof driverFactory !== 'function') {
- console.error('[TourManager] Driver.js not loaded or invalid. window.driver:', window.driver);
+ errorHandler.logError('[TourManager] Driver.js Not Loaded', new Error('Driver.js not loaded or invalid'), { windowDriver: typeof window.driver });
return false;
}
@@ -202,7 +204,7 @@
async showTooltip(tooltipId) {
const tooltip = window.TooltipDefinitions.getTooltipById(tooltipId);
if (!tooltip) {
- console.error(`[TourManager] Tooltip not found: ${tooltipId}`);
+ errorHandler.logError('[TourManager] Tooltip Not Found', new Error(`Tooltip not found: ${tooltipId}`), { tooltipId });
return;
}
diff --git a/status/js/weather.js b/status/js/weather.js
index b439a2d..1d235a6 100644
--- a/status/js/weather.js
+++ b/status/js/weather.js
@@ -1,5 +1,6 @@
// ========== WEATHER WIDGET ==========
(function() {
+ const errorHandler = new ErrorHandler();
// Inject modal HTML
injectModal('weather-modal', `
Weather Settings
@@ -166,7 +167,7 @@
weatherWidget.icon.innerHTML = `${escapeHtml(weather.icon)}`;
}
} catch (error) {
- console.error('Weather update error:', error);
+ errorHandler.logError('[Weather] Update Error', error, { function: 'updateWeather' });
weatherWidget.location.textContent = 'Weather Error';
weatherWidget.temp.textContent = 'Error';
weatherWidget.condition.textContent = 'Failed to load';