From 71e4d48d7617cf05dbe7338c3d6115d6a0a2c99c Mon Sep 17 00:00:00 2001 From: Meik Date: Sat, 21 Feb 2026 12:30:03 +0100 Subject: [PATCH] Fix login redirect loop on optional asset load failure --- web/index.html | 64 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/web/index.html b/web/index.html index 2e09514..7432a41 100644 --- a/web/index.html +++ b/web/index.html @@ -27,14 +27,15 @@ { href: 'daily-bookmarks.css', id: 'dailyBookmarksCss', disabled: true } ]; const jsFiles = [ - 'app.js', - 'dashboard.js', - 'settings.js', - 'ai-debug.js', - 'vendor/list.min.js', - 'automation.js', - 'daily-bookmarks.js', - 'trade-fairs.js' + { src: 'app.js' }, + { src: 'dashboard.js' }, + { src: 'settings.js' }, + { src: 'ai-debug.js' }, + { src: 'vendor/list.min.js' }, + { src: 'automation.js' }, + { src: 'daily-bookmarks.js' }, + // Optional: new bookmark subpage. If not yet deployed/cached, app must still boot. + { src: 'trade-fairs.js', optional: true } ]; function withVersion(value) { @@ -65,16 +66,51 @@ }); } + function normalizeScriptEntry(entry) { + if (typeof entry === 'string') { + return { src: entry, optional: false }; + } + return { + src: entry && entry.src ? entry.src : '', + optional: Boolean(entry && entry.optional) + }; + } + + function showBootstrapError(message) { + document.body.classList.remove('auth-pending'); + const loadingEl = document.getElementById('loading'); + const errorEl = document.getElementById('error'); + if (loadingEl) { + loadingEl.style.display = 'none'; + } + if (errorEl) { + errorEl.style.display = 'block'; + errorEl.textContent = message || 'Die Anwendung konnte nicht geladen werden.'; + } + } + function loadScriptsSequentially(list, index = 0) { return new Promise((resolve, reject) => { if (index >= list.length) { resolve(); return; } + const entry = normalizeScriptEntry(list[index]); + if (!entry.src) { + loadScriptsSequentially(list, index + 1).then(resolve).catch(reject); + return; + } const script = document.createElement('script'); - script.src = withVersion(list[index]); + script.src = withVersion(entry.src); script.onload = () => loadScriptsSequentially(list, index + 1).then(resolve).catch(reject); - script.onerror = reject; + script.onerror = () => { + if (entry.optional) { + console.warn('Optionales Script konnte nicht geladen werden:', entry.src); + loadScriptsSequentially(list, index + 1).then(resolve).catch(reject); + return; + } + reject(new Error(`Script konnte nicht geladen werden: ${entry.src}`)); + }; document.body.appendChild(script); }); } @@ -86,10 +122,14 @@ redirectToLogin(); return; } + if (!res.ok) { + throw new Error(`Session-Check fehlgeschlagen (${res.status})`); + } loadStyles(); await loadScriptsSequentially(jsFiles); - } catch (_error) { - redirectToLogin(); + } catch (error) { + console.error('Bootstrap fehlgeschlagen:', error); + showBootstrapError('Fehler beim Laden der Anwendung. Bitte Seite neu laden.'); } }