Add robust JSON parsing for server status and implement retry logic for fetching

This commit is contained in:
Fabian Schieder 2026-03-01 14:46:04 +01:00
parent 0e15466eee
commit 38ec4da90d

View File

@ -104,6 +104,19 @@ document.querySelectorAll('.card').forEach(card => {
return String(url).replace(/\/+$/, '');
};
const parsePossiblyUtf16Json = (text) => {
if (!text) return null;
// If server accidentally delivered UTF-16LE bytes, the browser may decode it with lots of \u0000.
// Remove NULs and common BOM remnants.
const cleaned = String(text)
.replace(/^\uFEFF/, '')
.replace(/\u0000/g, '')
.trim();
return JSON.parse(cleaned);
};
const applyPayload = (payload) => {
const byUrl = payload && payload.byUrl ? payload.byUrl : {};
const byUrlNormalized = payload && payload.byUrlNormalized ? payload.byUrlNormalized : {};
@ -136,15 +149,19 @@ document.querySelectorAll('.card').forEach(card => {
const fetchAndApply = async () => {
const res = await fetch('/server_status.php', { cache: 'no-store' });
if (!res.ok) throw new Error('status_fetch_failed');
const payload = await res.json();
// Use text() + robust JSON parse to survive wrong encoding (UTF-16/NULs).
const text = await res.text();
const payload = parsePossiblyUtf16Json(text);
if (!payload) throw new Error('status_json_empty');
applyPayload(payload);
};
// Ziel: nach ~1s sichtbar springen (nicht sofort beim ersten Paint).
// Falls der Endpoint kurz hängt, probieren wir 1-2x nochmal.
const attempts = [1000, 2000, 3500];
for (let i = 0; i < attempts.length; i++) {
await new Promise(r => setTimeout(r, attempts[i]));
// Nach ~1s einmal aktualisieren, dann (falls nötig) 2 schnelle Retries.
const delays = [1000, 1000, 1500];
for (const d of delays) {
await new Promise(r => setTimeout(r, d));
try {
await fetchAndApply();
break;