[PR #23213] [CLOSED] fix: harden file preview components against crashes and stale state #50134

Closed
opened 2026-04-30 02:42:20 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/open-webui/open-webui/pull/23213
Author: @Classic298
Created: 3/29/2026
Status: Closed

Base: devHead: fix/file-modal-robustness


📝 Commits (1)

  • a501195 fix: harden file preview components against crashes and stale state

📊 Changes

4 files changed (+89 additions, -186 deletions)

View changed files

📝 src/lib/components/chat/FileNav/FilePreview.svelte (+23 -75)
📝 src/lib/components/common/FileItemModal.svelte (+33 -28)
📝 src/lib/components/common/ImagePreview.svelte (+32 -81)
📝 src/lib/components/common/SVGPanZoom.svelte (+1 -2)

📄 Description

fix: harden file preview components against crashes and stale state

Fixes multiple crash paths, race conditions, dead code, and maintainability issues across the file preview components.

Crash fixes

  • FileItemModal TypeError on failed file fetch — When getFileById fails (network error, missing file), the modal template accessed item.file.data.content without optional chaining, throwing a TypeError and breaking the entire modal. Added proper optional chaining on all unguarded access paths.

  • FilePreview save button stuck forever — If onSave rejected in saveEdit or saveCodeFile, the saving flag was never reset. The save button became permanently disabled with no way to retry or cancel. Wrapped both functions in try/finally so the flag always resets.

Race condition fix

  • FileItemModal content mismatch on rapid switching — Opening file A then quickly switching to file B could render file A's Excel/DOCX/PPTX data under file B's name if the first async fetch completed after the second. Added a generation counter to loadContent so stale responses are discarded.

Functional fixes

  • Unreachable SVG source view in FilePreview — The Shiki syntax-highlighted SVG source branch was unreachable because the inline SVG preview branch always matched first (both checked isSvg && !showRaw). Removed the dead Shiki computation (which was wasting CPU on every SVG load) and replaced it with a proper isSvg && showRaw branch using FileCodeEditor, matching the pattern used by HTML and Markdown.

  • DOMPurify data- attributes silently stripped in SVGPanZoom* — The ADD_ATTR config used "data-*" as a glob pattern, but DOMPurify treats it as a literal attribute name. Data attributes on SVG content (common in Mermaid diagrams) were silently removed. Replaced with ALLOW_DATA_ATTR: true, which is the correct API.

  • isCode detection divergence between FileItemModal and FilePreview — FileItemModal hardcoded ~20 extensions while FilePreview used the shared isCodeFile utility. Files recognized as code in one context weren't in the other. Replaced the hardcoded list with the shared utility.

Cleanup

  • Stale office state between items — Excel/DOCX/PPTX state variables (excelHtml, docxHtml, pptxSlides, etc.) were not reset when switching items. Currently gated by template conditionals but would surface stale data if those conditionals ever changed. Now explicitly reset at the start of loadContent.

  • Triplicated download logic in ImagePreview — The blob URL and remote URL download branches were identical copy-paste. Consolidated into a single downloadImage function.

  • Dead variables and console.log statements — Removed unused mounted and sceneParentElement variables from ImagePreview, and removed stray console.log calls from FileItemModal, ImagePreview, and SVGPanZoom.

Contributor License Agreement

Note

Deleting the CLA section will lead to immediate closure of your PR and it will not be merged in.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/open-webui/open-webui/pull/23213 **Author:** [@Classic298](https://github.com/Classic298) **Created:** 3/29/2026 **Status:** ❌ Closed **Base:** `dev` ← **Head:** `fix/file-modal-robustness` --- ### 📝 Commits (1) - [`a501195`](https://github.com/open-webui/open-webui/commit/a501195a6834ee4d84e78cdb79fcc18ecc68f7f6) fix: harden file preview components against crashes and stale state ### 📊 Changes **4 files changed** (+89 additions, -186 deletions) <details> <summary>View changed files</summary> 📝 `src/lib/components/chat/FileNav/FilePreview.svelte` (+23 -75) 📝 `src/lib/components/common/FileItemModal.svelte` (+33 -28) 📝 `src/lib/components/common/ImagePreview.svelte` (+32 -81) 📝 `src/lib/components/common/SVGPanZoom.svelte` (+1 -2) </details> ### 📄 Description ## fix: harden file preview components against crashes and stale state Fixes multiple crash paths, race conditions, dead code, and maintainability issues across the file preview components. ### Crash fixes - **FileItemModal TypeError on failed file fetch** — When getFileById fails (network error, missing file), the modal template accessed item.file.data.content without optional chaining, throwing a TypeError and breaking the entire modal. Added proper optional chaining on all unguarded access paths. - **FilePreview save button stuck forever** — If onSave rejected in saveEdit or saveCodeFile, the saving flag was never reset. The save button became permanently disabled with no way to retry or cancel. Wrapped both functions in try/finally so the flag always resets. ### Race condition fix - **FileItemModal content mismatch on rapid switching** — Opening file A then quickly switching to file B could render file A's Excel/DOCX/PPTX data under file B's name if the first async fetch completed after the second. Added a generation counter to loadContent so stale responses are discarded. ### Functional fixes - **Unreachable SVG source view in FilePreview** — The Shiki syntax-highlighted SVG source branch was unreachable because the inline SVG preview branch always matched first (both checked isSvg && !showRaw). Removed the dead Shiki computation (which was wasting CPU on every SVG load) and replaced it with a proper isSvg && showRaw branch using FileCodeEditor, matching the pattern used by HTML and Markdown. - **DOMPurify data-* attributes silently stripped in SVGPanZoom** — The ADD_ATTR config used "data-*" as a glob pattern, but DOMPurify treats it as a literal attribute name. Data attributes on SVG content (common in Mermaid diagrams) were silently removed. Replaced with ALLOW_DATA_ATTR: true, which is the correct API. - **isCode detection divergence between FileItemModal and FilePreview** — FileItemModal hardcoded ~20 extensions while FilePreview used the shared isCodeFile utility. Files recognized as code in one context weren't in the other. Replaced the hardcoded list with the shared utility. ### Cleanup - **Stale office state between items** — Excel/DOCX/PPTX state variables (excelHtml, docxHtml, pptxSlides, etc.) were not reset when switching items. Currently gated by template conditionals but would surface stale data if those conditionals ever changed. Now explicitly reset at the start of loadContent. - **Triplicated download logic in ImagePreview** — The blob URL and remote URL download branches were identical copy-paste. Consolidated into a single downloadImage function. - **Dead variables and console.log statements** — Removed unused mounted and sceneParentElement variables from ImagePreview, and removed stray console.log calls from FileItemModal, ImagePreview, and SVGPanZoom. ### Contributor License Agreement <!-- 🚨 DO NOT DELETE THE TEXT BELOW 🚨 Keep the "Contributor License Agreement" confirmation text intact. Deleting it will trigger the CLA-Bot to INVALIDATE your PR. Your PR will NOT be reviewed or merged until you check the box below confirming that you have read and agree to the terms of the CLA. --> - [X] By submitting this pull request, I confirm that I have read and fully agree to the [Contributor License Agreement (CLA)](https://github.com/open-webui/open-webui/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT), and I am providing my contributions under its terms. > [!NOTE] > Deleting the CLA section will lead to immediate closure of your PR and it will not be merged in. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-30 02:42:20 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#50134