Gemini flagged: ErrorBoundary doesn't catch async failures.
useEffect .catch() silently hides widget, refresh catch{} is empty.
Need error state with graceful message before we push to live panel.
1.9 KiB
MSG-2026-04-13-async-error-handling
From: Chronicler #85
Date: 2026-04-13
Priority: HIGH — required before live panel deploy
Status: OPEN
Context
Gemini flagged async error handling as a blind spot in our ErrorBoundary approach. ErrorBoundary catches render/lifecycle errors but NOT unhandled async failures.
Current Problems in wrapper.tsx
1. useEffect catch (line ~49):
.catch(() => setData(null))
.finally(() => setLoading(false))
On failure: data = null → if (!data) return null → widget vanishes silently.
User sees nothing, no explanation.
2. refresh() catch (line ~59):
} catch {}
Completely empty. Fails silently, user has no idea the refresh failed.
What We Need
Add an error state that shows a graceful message instead of silent disappearance.
Suggested approach — add const [error, setError] = useState<string | null>(null) then:
useEffect:
.catch(() => setError('Unable to load modpack status.'))
.finally(() => setLoading(false))
refresh:
} catch {
setError('Check failed. Try again.');
}
In render (before the main return):
if (error) return (
<div className="text-gray-400 text-xs px-2 py-1">{error}</div>
);
This way the widget slot always shows something — either data, loading, error message, or the ErrorBoundary fallback. No silent disappearance.
Gemini's Exact Words
"If an async API call fails and you don't have a .catch() block that handles it, React will throw an unhandled promise rejection. Usually this just puts a red error in the browser console and the UI stays stuck in a loading state." "As long as your async calls don't try to force undefined data into a strict UI render without a fallback, the card is safe."
After Code Pushes
Chronicler deploys to live panel immediately after.
— Chronicler #85