diff --git a/status/js/app-selector.js b/status/js/app-selector.js index 60c7c4a..3855161 100644 --- a/status/js/app-selector.js +++ b/status/js/app-selector.js @@ -1,5 +1,6 @@ // App Selector System (function () { + const errorHandler = new ErrorHandler(); injectModal('app-selector-modal', `

Choose an App

@@ -230,7 +231,7 @@ return true; } } catch (e) { - console.error('Failed to fetch app templates:', e); + errorHandler.logError('[AppSelector] Fetch Templates', e, { function: 'fetchApiTemplates' }); } return false; } @@ -242,7 +243,7 @@ const data = await response.json(); return data; } catch (e) { - console.error('Failed to check port:', e); + errorHandler.logError('[AppSelector] Check Port', e, { function: 'checkPortAvailability' }); return { available: true }; // Assume available on error } } @@ -256,7 +257,7 @@ return data.suggestedPort; } } catch (e) { - console.error('Failed to get suggested port:', e); + errorHandler.logError('[AppSelector] Get Suggested Port', e, { function: 'getSuggestedPort' }); } return basePort; } @@ -842,7 +843,7 @@ throw new Error(result.error || 'Deployment failed'); } } catch (error) { - console.error('Deployment error:', error); + errorHandler.logError('[AppSelector] Deployment', error, { function: 'deploy' }); showNotification( `Failed to deploy ${appTemplate.name}: ${error.message}`, 'error', diff --git a/status/js/globals.js b/status/js/globals.js index 8153266..31d4642 100644 --- a/status/js/globals.js +++ b/status/js/globals.js @@ -24,6 +24,9 @@ const DC = { }, }; +// Error handler for tracking issues +const errorHandler = new ErrorHandler(); + // ===== GLOBAL SITE CONFIG (loaded from server, cached in localStorage) ===== // Only non-sensitive display preferences are cached; DNS IPs/topology are fetched from API const _cachedCfg = JSON.parse(localStorage.getItem('dashcaddy_site_config') || 'null'); @@ -160,7 +163,7 @@ async function getCSRFToken() { csrfToken = data.token; return csrfToken; } catch (error) { - console.error('Failed to get CSRF token:', error); + errorHandler.logError('[CSRF] Get Token', error, { function: 'getCSRFToken' }); throw error; } } @@ -185,7 +188,7 @@ async function secureFetch(url, options = {}) { 'X-CSRF-Token': token }; } catch (error) { - console.error('Failed to add CSRF token to request:', error); + errorHandler.logError('[CSRF] Add to Request', error, { function: 'secureFetch' }); } } diff --git a/status/js/notification-settings.js b/status/js/notification-settings.js index 636630e..8d41809 100644 --- a/status/js/notification-settings.js +++ b/status/js/notification-settings.js @@ -1,5 +1,6 @@ // ========== NOTIFICATION SETTINGS ========== (function() { + const errorHandler = new ErrorHandler(); // Inject modal HTML injectModal('notifications-modal', `
@@ -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';