fix(news): use Promise.allSettled for resilience, deduplicate items, guard categories
Build & Deploy / build-and-deploy (push) Successful in 2m15s

This commit is contained in:
svemagie
2026-04-19 12:45:46 +02:00
parent 2e911fcc35
commit 72125da01e
+25 -7
View File
@@ -161,7 +161,7 @@ withSidebar: true
<span x-show="item.author || item.blog?.title" x-text="'by ' + (item.author || item.blog?.title)"></span>
<time class="font-mono text-sm" :datetime="item.published" x-text="formatDate(item.published)"></time>
<span class="hidden sm:inline" x-show="item.categories?.length">
<template x-for="cat in item.categories.slice(0, 3)" :key="cat">
<template x-for="cat in (item.categories || []).slice(0, 3)" :key="cat">
<span class="text-accent-600 dark:text-accent-400" x-text="'#' + cat"></span>
</template>
</span>
@@ -387,12 +387,25 @@ function newsApp() {
this.error = null;
try {
const [itemsRes, feedsRes, statusRes] = await Promise.all([
fetch('/rssapi/api/items?limit=50').then(r => r.json()),
fetch('/rssapi/api/feeds').then(r => r.json()),
fetch('/rssapi/api/status').then(r => r.json())
const [itemsResult, feedsResult, statusResult] = await Promise.allSettled([
fetch('/rssapi/api/items?limit=50').then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); }),
fetch('/rssapi/api/feeds').then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); }),
fetch('/rssapi/api/status').then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); })
]);
if (itemsResult.status === 'rejected') {
this.error = 'Failed to load news: ' + itemsResult.reason.message;
console.error('News items fetch error:', itemsResult.reason);
return;
}
const itemsRes = itemsResult.value;
const feedsRes = feedsResult.status === 'fulfilled' ? feedsResult.value : { feeds: [] };
const statusRes = statusResult.status === 'fulfilled' ? statusResult.value : null;
if (feedsResult.status === 'rejected') console.warn('News feeds fetch failed (non-critical):', feedsResult.reason);
if (statusResult.status === 'rejected') console.warn('News status fetch failed (non-critical):', statusResult.reason);
this.items = itemsRes.items || [];
this.pagination = itemsRes.pagination || null;
this.feeds = feedsRes.feeds || [];
@@ -429,8 +442,13 @@ function newsApp() {
},
get filteredItems() {
if (this.filterFeed === 'all') return this.items;
return this.items.filter(item => item.feedId === this.filterFeed);
const seen = new Set();
const base = this.filterFeed === 'all' ? this.items : this.items.filter(item => item.feedId === this.filterFeed);
return base.filter(item => {
if (seen.has(item.id)) return false;
seen.add(item.id);
return true;
});
},
getFeedUrl(feedId) {