Refactor server status fetching to use a dynamic endpoint and improve JSON parsing error handling
This commit is contained in:
parent
38ec4da90d
commit
4ebb0bc9c1
@ -99,6 +99,8 @@ document.querySelectorAll('.card').forEach(card => {
|
||||
const cards = Array.from(document.querySelectorAll('.card[data-status-url]'));
|
||||
if (cards.length === 0) return;
|
||||
|
||||
const endpoint = './server_status.php';
|
||||
|
||||
const normalize = (url) => {
|
||||
if (!url) return '';
|
||||
return String(url).replace(/\/+$/, '');
|
||||
@ -106,14 +108,10 @@ document.querySelectorAll('.card').forEach(card => {
|
||||
|
||||
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(/^?\uFEFF/, '')
|
||||
.replace(/\u0000/g, '')
|
||||
.trim();
|
||||
|
||||
return JSON.parse(cleaned);
|
||||
};
|
||||
|
||||
@ -121,6 +119,7 @@ document.querySelectorAll('.card').forEach(card => {
|
||||
const byUrl = payload && payload.byUrl ? payload.byUrl : {};
|
||||
const byUrlNormalized = payload && payload.byUrlNormalized ? payload.byUrlNormalized : {};
|
||||
|
||||
let applied = 0;
|
||||
for (const card of cards) {
|
||||
const key = normalize(card.getAttribute('data-status-url'));
|
||||
const svc = byUrl[key] || byUrl[key + '/'] || byUrlNormalized[key] || null;
|
||||
@ -143,22 +142,29 @@ document.querySelectorAll('.card').forEach(card => {
|
||||
badge.textContent = 'Unbekannt';
|
||||
badge.title = svc.detail || 'Unbekannt';
|
||||
}
|
||||
applied++;
|
||||
}
|
||||
|
||||
console.debug('[server-status] applied badges:', applied);
|
||||
};
|
||||
|
||||
const fetchAndApply = async () => {
|
||||
const res = await fetch('/server_status.php', { cache: 'no-store' });
|
||||
if (!res.ok) throw new Error('status_fetch_failed');
|
||||
const res = await fetch(endpoint, { cache: 'no-store' });
|
||||
if (!res.ok) throw new Error('status_fetch_failed_' + res.status);
|
||||
|
||||
// Use text() + robust JSON parse to survive wrong encoding (UTF-16/NULs).
|
||||
const text = await res.text();
|
||||
const payload = parsePossiblyUtf16Json(text);
|
||||
let payload;
|
||||
try {
|
||||
payload = parsePossiblyUtf16Json(text);
|
||||
} catch (e) {
|
||||
console.warn('[server-status] JSON parse failed, first 120 chars:', text.slice(0, 120));
|
||||
throw e;
|
||||
}
|
||||
if (!payload) throw new Error('status_json_empty');
|
||||
|
||||
applyPayload(payload);
|
||||
};
|
||||
|
||||
// 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));
|
||||
@ -166,7 +172,7 @@ document.querySelectorAll('.card').forEach(card => {
|
||||
await fetchAndApply();
|
||||
break;
|
||||
} catch (e) {
|
||||
// keep unknown and retry
|
||||
console.warn('[server-status] update failed:', e);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user