fix: blog TRANSMISSION ERROR - coffee=6 caused RangeError in String.repeat(-1) - Clamp buildCoffee val to 0-5 range - Fix post data: cap coffee at 5 - Add per-card error protection in rendering - Fix fallback URL to absolute path - Show detailed error messages for debugging

This commit is contained in:
jae 2026-04-02 01:16:09 +00:00
parent 672fcf3f37
commit ada2ba1062
2 changed files with 22 additions and 9 deletions

View file

@ -18,7 +18,7 @@
"motivation": 5,
"focus": 4,
"difficulty": 3,
"coffee": 6,
"coffee": 5,
"heart_rate": 76,
"threat_level": "LOW"
},

View file

@ -51,6 +51,7 @@
// ─── Coffee Icons ───
function buildCoffee(val) {
val = Math.max(0, Math.min(5, val || 0));
return '<span class="stat-coffee">' + '☕'.repeat(val) + '<span style="opacity:0.2">' + '☕'.repeat(5 - val) + '</span></span>';
}
@ -105,17 +106,28 @@
try {
const res = await fetch(API + '/posts');
if (!res.ok) throw new Error('API error');
if (!res.ok) throw new Error('API ' + res.status);
const posts = await res.json();
if (posts.length === 0) {
if (!Array.isArray(posts) || posts.length === 0) {
grid.innerHTML = '<div class="blog-loading">NO TRANSMISSIONS FOUND</div>';
return;
}
// Sort by date descending
posts.sort((a, b) => new Date(b.date) - new Date(a.date));
grid.innerHTML = posts.map(renderPostCard).join('');
// Render each card with individual error protection
let html = '';
posts.forEach((post, idx) => {
try {
html += renderPostCard(post);
} catch (cardErr) {
console.error('Card render error for post ' + idx + ':', cardErr);
html += '<article class="post-card"><div class="post-card-content" style="padding:1.5rem"><h2 class="post-card-title">RENDER ERROR</h2><p style="color:#ff4444;font-size:0.8rem">' + cardErr.message + '</p></div></article>';
}
});
grid.innerHTML = html;
// Animate cards in
const cards = grid.querySelectorAll('.post-card');
@ -130,9 +142,11 @@
});
} catch (err) {
// Fallback: load from static JSON
console.error('Blog primary load error:', err);
// Fallback: load from static JSON (absolute path)
try {
const res2 = await fetch('api/data/posts.json');
const res2 = await fetch('/api/data/posts.json');
if (!res2.ok) throw new Error('Fallback ' + res2.status);
const posts = await res2.json();
posts.sort((a, b) => new Date(b.date) - new Date(a.date));
grid.innerHTML = posts.map(renderPostCard).join('');
@ -147,12 +161,11 @@
}, 100 + i * 150);
});
} catch (e2) {
grid.innerHTML = '<div class="blog-loading">TRANSMISSION ERROR — RETRY LATER</div>';
console.error('Blog fallback error:', e2);
grid.innerHTML = '<div class="blog-loading">TRANSMISSION ERROR: ' + err.message + ' / FALLBACK: ' + e2.message + '</div>';
}
}
}
// ─── Filters ───
function initFilters() {
const btns = document.querySelectorAll('.filter-btn');
btns.forEach(btn => {