Fix ActivityFeed fetch TypeError: add proper error handling and type safety

This commit is contained in:
2026-01-10 17:03:07 +01:00
parent 80f2ac61ac
commit 2a260abe0a

View File

@@ -77,42 +77,85 @@ export default function ActivityFeed() {
// Fetch data every 30 seconds (optimized to match server cache)
useEffect(() => {
// Don't fetch if tracking is disabled
if (!isTrackingEnabled) {
// Don't fetch if tracking is disabled or during SSR
if (!isTrackingEnabled || typeof window === 'undefined') {
return;
}
const fetchData = async () => {
try {
// Check if fetch is available (should be, but safety check)
if (typeof fetch === 'undefined') {
return;
}
// Add timestamp to prevent aggressive caching but respect server cache
const res = await fetch("/api/n8n/status", {
cache: "default",
}).catch((fetchError) => {
// Handle network errors gracefully
if (process.env.NODE_ENV === 'development') {
console.warn('ActivityFeed: Fetch failed:', fetchError);
}
return null;
});
if (!res.ok) return;
let json = await res.json();
if (!res || !res.ok) {
if (process.env.NODE_ENV === 'development' && res) {
console.warn('ActivityFeed: API returned non-OK status:', res.status);
}
return;
}
let json: unknown;
try {
json = await res.json();
} catch (parseError) {
if (process.env.NODE_ENV === 'development') {
console.warn('ActivityFeed: Failed to parse JSON response:', parseError);
}
return;
}
if (process.env.NODE_ENV === 'development') {
console.log("ActivityFeed data (raw):", json);
}
// Handle array response if API returns it wrapped
if (Array.isArray(json)) {
json = json[0] || null;
}
if (process.env.NODE_ENV === 'development') {
console.log("ActivityFeed data (processed):", json);
}
setData(json);
if (!json || typeof json !== 'object') {
return;
}
// Type assertion - API should return StatusData format
const activityData = json as StatusData;
setData(activityData);
// Check if there's any active activity
const hasActiveActivity =
json.coding?.isActive ||
json.gaming?.isPlaying ||
json.music?.isPlaying;
const coding = activityData.coding;
const gaming = activityData.gaming;
const music = activityData.music;
const hasActiveActivity = Boolean(
coding?.isActive ||
gaming?.isPlaying ||
music?.isPlaying
);
if (process.env.NODE_ENV === 'development') {
console.log("Has activity:", hasActiveActivity, {
coding: json.coding?.isActive,
gaming: json.gaming?.isPlaying,
music: json.music?.isPlaying,
coding: coding?.isActive,
gaming: gaming?.isPlaying,
music: music?.isPlaying,
});
}
setHasActivity(hasActiveActivity);
@@ -120,8 +163,12 @@ export default function ActivityFeed() {
if (hasActiveActivity && !isMinimized) {
setIsExpanded(true);
}
} catch (e) {
console.error("Failed to fetch activity", e);
} catch (error) {
// Silently fail - activity feed is not critical
if (process.env.NODE_ENV === 'development') {
console.error("Failed to fetch activity:", error);
}
// Don't set error state - just fail silently
}
};