Editor's session restore (per #161) restores the editor's state from sessionStorage, but the gallery designs list is in localStorage — user with a stale localStorage (e.g., cleared it) gets a 'design not found' error in the editor with no graceful re… #309

Closed
opened 2026-10-04 03:49:45 +00:00 by Mark · 1 comment
Owner

Finding

The editor reads the design from tc_workspace_snapshot (sessionStorage). The Gallery's designs are in localStorage.designs (per #148). If the user:

  • Opens a design in the editor (cached in sessionStorage)
  • Clears localStorage (e.g., via DevTools, or in a different browser tab)
  • Refreshes the editor
  • The sessionStorage has the design's data, but the Gallery's reference to it is gone

grep -rn 'design.*not.*found\|handleMissingDesign' src/pages/Editor.tsx returns 0. The editor doesn't handle the case where the design's data is incomplete or the loadedDesignId points to a non-existent design.

A user with a stale localStorage:

  • Editor loads from sessionStorage
  • Tries to update the Gallery on Save
  • The save fails (no design with that ID exists)
  • Generic error toast

The fix is a graceful recovery: detect the missing design and either re-save as a new design, or warn the user.

Where

  • Editor's save: src/pages/Editor.tsx:handleSave (line 832)
  • sessionStorage: src/pages/Editor.tsx:loadInitialFilename etc.
  • Gallery's localStorage: localStorage.getItem('designs')
  • No missing-design handling: grep -rn 'design.*not.*found' src/pages/Editor.tsx returns 0

Suggested fix shape

  1. Detect: when loading, check if loadedDesignIdRef.current matches a design in the Gallery. If not, log a warning and treat as a new design.

  2. Save flow: when saving with a loadedDesignId that doesn't exist in the Gallery:

  • Show a modal: "This design was not found in your Gallery. Save as a new design?"
  • Confirm → save as new (per #187)
  • Cancel → keep the editor open, the user can save manually
  1. Auto-save: the session restore (per #161) auto-saves to sessionStorage. If the user closes the editor and reopens later, the design is still there. The recovery is only needed if the Gallery's localStorage is cleared.

  2. Edge case: if the user has a different browser profile, the Gallery's localStorage is per-profile, but sessionStorage is also per-profile. The mismatch is rare but possible.

Severity

Low. The user can re-save. Edge case.

Discovered by

Code review (2026-10-02) of editor save flow.

  • #161 (open) — Editor session restore. The session is the data source; the localStorage is the Gallery.
  • #148 (closed) — Gallery's localStorage. The Gallery's storage; the editor references it.
  • The save error handling (per #243) is for the "no changes" case; this is the "design not found" case.
## Finding The editor reads the design from `tc_workspace_snapshot` (sessionStorage). The Gallery's designs are in `localStorage.designs` (per #148). If the user: - Opens a design in the editor (cached in sessionStorage) - Clears localStorage (e.g., via DevTools, or in a different browser tab) - Refreshes the editor - The sessionStorage has the design's data, but the Gallery's reference to it is gone `grep -rn 'design.*not.*found\|handleMissingDesign' src/pages/Editor.tsx` returns 0. The editor doesn't handle the case where the design's data is incomplete or the loadedDesignId points to a non-existent design. A user with a stale localStorage: - Editor loads from sessionStorage - Tries to update the Gallery on Save - The save fails (no design with that ID exists) - Generic error toast The fix is a graceful recovery: detect the missing design and either re-save as a new design, or warn the user. ## Where - Editor's save: `src/pages/Editor.tsx:handleSave` (line 832) - sessionStorage: `src/pages/Editor.tsx:loadInitialFilename` etc. - Gallery's localStorage: `localStorage.getItem('designs')` - No missing-design handling: `grep -rn 'design.*not.*found' src/pages/Editor.tsx` returns 0 ## Suggested fix shape 1. **Detect**: when loading, check if `loadedDesignIdRef.current` matches a design in the Gallery. If not, log a warning and treat as a new design. 2. **Save flow**: when saving with a `loadedDesignId` that doesn't exist in the Gallery: - Show a modal: "This design was not found in your Gallery. Save as a new design?" - Confirm → save as new (per #187) - Cancel → keep the editor open, the user can save manually 3. **Auto-save**: the session restore (per #161) auto-saves to sessionStorage. If the user closes the editor and reopens later, the design is still there. The recovery is only needed if the Gallery's localStorage is cleared. 4. **Edge case**: if the user has a different browser profile, the Gallery's localStorage is per-profile, but sessionStorage is also per-profile. The mismatch is rare but possible. ## Severity Low. The user can re-save. Edge case. ## Discovered by Code review (2026-10-02) of editor save flow. ## Related - #161 (open) — Editor session restore. The session is the data source; the localStorage is the Gallery. - #148 (closed) — Gallery's localStorage. The Gallery's storage; the editor references it. - The save error handling (per #243) is for the "no changes" case; this is the "design not found" case.
Mark closed this issue 2026-10-04 22:10:35 +00:00
Author
Owner

Shipped in fa03760 (bundled with #308 multi-document tabs) + 194fd2f (test).

Editor.handleSave now intercepts the case where loadedDesignId points at a row no longer present in localStorage and opens a confirmation modal instead of silently creating a fresh row via saveDesignToGallery's addDesign fallback.

Modal affordances:

  • "Save as new" → drops the loaded id ref and runs handleSaveAsNew, creating a fresh Gallery row
  • "Cancel" → closes the dialog without touching localStorage

Also noted in the issue: the original "save fails with a generic error toast" claim was inaccurate — saveDesignToGallery already fell through to addDesign. The actual UX problem was the silent fall-through (user thought they'd update an existing row but got a brand-new one). The modal makes the recovery explicit.

Shipped in fa03760 (bundled with #308 multi-document tabs) + 194fd2f (test). Editor.handleSave now intercepts the case where `loadedDesignId` points at a row no longer present in localStorage and opens a confirmation modal instead of silently creating a fresh row via saveDesignToGallery's addDesign fallback. Modal affordances: - "Save as new" → drops the loaded id ref and runs handleSaveAsNew, creating a fresh Gallery row - "Cancel" → closes the dialog without touching localStorage Also noted in the issue: the original "save fails with a generic error toast" claim was inaccurate — saveDesignToGallery already fell through to addDesign. The actual UX problem was the silent fall-through (user thought they'd update an existing row but got a brand-new one). The modal makes the recovery explicit.
Sign in to join this conversation.
No description provided.