Add centralized error handling with UI toast for user-facing errors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
erik 2026-02-26 09:33:57 +00:00
parent 16861ba88a
commit 40198fa0cf
2 changed files with 39 additions and 8 deletions

View file

@ -26,6 +26,17 @@
const DEBUG = false;
function debugLog(...args) { if (DEBUG) console.log(...args); }
function handleError(context, error, showUI = false) {
console.error(`[${context}]`, error);
if (showUI) {
const msg = document.createElement('div');
msg.className = 'error-toast';
msg.textContent = `${context}: ${error.message || 'Unknown error'}`;
document.body.appendChild(msg);
setTimeout(() => msg.remove(), GLOW_DURATION_MS);
}
}
/* ---------- DOM references --------------------------------------- */
const wrap = document.getElementById('mapContainer');
const group = document.getElementById('mapGroup');
@ -574,7 +585,7 @@ async function fetchHeatmapData() {
debugLog(`Loaded ${heatmapData.length} heat map points from last ${data.hours_window} hours`);
renderHeatmap();
} catch (err) {
console.error('Failed to fetch heat map data:', err);
handleError('Heatmap', err);
}
}
@ -659,7 +670,7 @@ async function fetchPortalData() {
debugLog(`Loaded ${portalData.length} portals from last hour`);
renderPortals();
} catch (err) {
console.error('Failed to fetch portal data:', err);
handleError('Portals', err);
}
}
@ -1057,8 +1068,8 @@ function showInventoryWindow(name) {
invContent.appendChild(count);
})
.catch(err => {
handleError('Inventory', err, true);
loading.textContent = `Failed to load inventory: ${err.message}`;
console.error('Inventory fetch failed:', err);
});
debugLog('Inventory window created for:', name);
@ -1365,7 +1376,7 @@ async function pollLive() {
renderTrails(trails);
renderList();
} catch (e) {
console.error('Live or trails fetch failed:', e);
handleError('Player update', e);
}
}
@ -1375,7 +1386,7 @@ async function pollTotalRares() {
const data = await response.json();
updateTotalRaresDisplay(data);
} catch (e) {
console.error('Total rares fetch failed:', e);
handleError('Rare counter', e);
}
}
@ -1394,7 +1405,7 @@ async function pollTotalKills() {
const data = await response.json();
updateTotalKillsDisplay(data);
} catch (e) {
console.error('Total kills fetch failed:', e);
handleError('Kill counter', e);
}
}
@ -1411,7 +1422,7 @@ async function pollServerHealth() {
const data = await response.json();
updateServerStatusDisplay(data);
} catch (e) {
console.error('Server health fetch failed:', e);
handleError('Server health', e);
updateServerStatusDisplay({ status: 'error' });
}
}
@ -1835,7 +1846,7 @@ function initWebSocket() {
}
});
socket.addEventListener('close', () => setTimeout(initWebSocket, 2000));
socket.addEventListener('error', e => console.error('WebSocket error:', e));
socket.addEventListener('error', e => handleError('WebSocket', e));
}
// Display or create a chat window for a character