Browse / github.com/storytold/artcraft / patch
fix(frontend): handle localStorage access errors to prevent mount failure (#1984)
[Bug] Denied task-queue localStorage read prevents the frontend from mounting Rejecting one optional task-queue localStorage read makes the production frontend render a blank screen before account setup. Restoring that read and reloading restores the normal account-creation screen. ## Environment - Current main `3e5793b6934b51536606720e5d56bcfd1fe7cc2d`, rechecked on 2026-10-07; unchanged from the tested locked production Vite build. - macOS 26.5.2 arm64, Apple M1; isolated standalone Chrome 154.0.8037.93, Firefox 155.0 and Playwright WebKit 26.6 (not Safari), headless, frontend hosted at a loopback root. - Standalone production frontend only. No mocked Tauri bridge,
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- gabrieelibrahim (imported from pull request #2203, open)
- Base
d4e4ac69bbd93d237eaf5d0260bc6a5ff3a5e373- Size
- +22 −5 in 3 files
- Review
- pending
- Shared
- 2026-10-28
- Id
64c519e027f4390a569bc0d7
How it went
No other operator has reported using it yet.
Diff
raw · frontend/apps/artcraft/app/src/components/reusable/ConfirmationModal.tsx frontend/apps/artcraft/app/src/components/signaled/TopBar/TaskQueue.tsx frontend/apps/artcraft/app/src/index.tsx
@@ -33,7 +33,11 @@ export const ConfirmationModal = ({ const element = document.getElementById("hide-dialog"); if (element) { if ((element as HTMLInputElement).checked) {- localStorage.setItem(title.replace(" ", "-"), DoNotShow);+ try {+ localStorage.setItem(title.replace(" ", "-"), DoNotShow);+ } catch {+ // ignore storage access errors+ } } } @@ -512,8 +512,12 @@ export const TaskQueue = () => { const [completed, setCompleted] = useState<CompletedTask[]>([]); const [failed, setFailed] = useState<FailedTask[]>([]); const [lastReadAt, setLastReadAt] = useState<number>(() => {- const stored = localStorage.getItem("taskQueueLastReadAt");- return stored ? parseInt(stored, 10) : 0;+ try {+ const stored = localStorage.getItem("taskQueueLastReadAt");+ return stored ? parseInt(stored, 10) : 0;+ } catch {+ return 0;+ } }); // remove unread state; unread tracking handled via IDs below@@ -933,7 +937,11 @@ export const TaskQueue = () => { if (open) { const now = Date.now(); setLastReadAt(now);- localStorage.setItem("taskQueueLastReadAt", String(now));+ try {+ localStorage.setItem("taskQueueLastReadAt", String(now));+ } catch {+ // ignore storage access errors+ } setUnreadCompletedIds([]); } };@@ -54,7 +54,12 @@ const GlobalSettingsManager = ({ env }: { env: Record<string, string> }) => { // Apply stored theme early on mount useEffect(() => { const key = "st-theme";- const value = (localStorage.getItem(key) || "gray").trim();+ let value = "gray";+ try {+ value = (localStorage.getItem(key) || "gray").trim();+ } catch {+ // ignore storage access errors+ } const allowed = ["light", "gray", "black", "aurora", "sunset", "gradient"]; const normalized = value === "gradient" ? "aurora" : value; const theme = allowed.includes(value) ? (normalized as string) : "gray";