fix(view,text-editor): give the blob read path a failure state - #11015
Closed
clayrisser wants to merge 1 commit into
Closed
fix(view,text-editor): give the blob read path a failure state#11015clayrisser wants to merge 1 commit into
clayrisser wants to merge 1 commit into
Conversation
Three read-path sites had no failure handling. TextViewer awaited fetch with no try/catch, so a rejection left an unhandled promise and a spinner that never resolves, and a non-2xx response was rendered as the file's contents. ImageViewer had on:load but no on:error, so a broken image kept the loading state set forever. The embed nodeview's provider promise had .then/.finally but no .catch, so a rejection left an unhandled rejection and no fallback to StubEmbedNodeView. Each now settles into a state that already exists: the FailedToPreview label for the two viewers, the stub view for the embed. No new i18n. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Clay Risser <clayrisser@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
clayrisser
force-pushed
the
fix/read-path-viewer-error-states
branch
from
August 13, 2026 06:47
bb2b33c to
b33ffec
Compare
Author
|
Closing — this was opened by an automated agent without my intent. Apologies for the noise. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Three places on the blob read path have no failure state at all. In each case a failed fetch leaves the UI stuck rather than showing the "Failed to preview" state the codebase already has.
1.
TextViewer.svelte:24-36awaitsfetchwith notry/catch:If the fetch rejects,
loading = falseis never reached — so the spinner runs forever — and the rejection is unhandled. A non-2xx response is worse than that: it does not reject, sores.text()succeeds and the error body is rendered as the file's contents.2.
ImageViewer.sveltehason:loadbut noon:error. Same eternal spinner:_setLoading(false)only ever runs fromon:load, so a broken image leaves the loading state set and the<img>pinned atheight: 0.3.
embed.ts:122has.thenand.finallybut no.catch:A rejected provider promise is an unhandled rejection, and the nodeview never falls back to
StubEmbedNodeView— so the embed renders as nothing at all, rather than as the stub link it is designed to degrade to.Fix
Each path now settles into a state that already exists in the codebase —
presentation.string.FailedToPreviewfor the two viewers (already defined atpackages/presentation/src/plugin.ts:138and translated inlang/en.json, so no new i18n), and the existing stub view for the embed.TextViewer— wrap intry/catch/finally, treat!res.okas an error rather than rendering the body, and add an{:else if error}branch showingFailedToPreview.ImageViewer— adderrorstate, anon:errorhandler on the<img>, and an error branch. Theerrorflag resets alongside_setLoading(true)whenvaluechanges, so navigating from a broken image to a good one recovers.embed.ts— add a.catchthat warns and returnsundefined, which the existingview = view ?? StubEmbedNodeViewline then turns into the stub.Scope and residual risk
ImageViewerdiff looks larger than it is: adding the{#if error}branch re-indents the existingDrawingBoardblock into the{:else}. The only substantive changes are theerrorvariable, theon:errorhandler, and the reset.TextViewernow treats a non-2xx response as a failure rather than rendering the response body as file contents. That is a deliberate behaviour change and the one thing here worth a second opinion — it is the right call for a file viewer, but it does mean a server that returns a 404 page with useful text will now show "Failed to preview" instead of that text.console.warns are the only new output. If you would rather they went through a measure context, say so and I will change them.Verification
Verified against
develop@1be6047c8:TextViewer.svelte:33is still a bareawait fetch,ImageViewer.sveltestill has zeroon:errorhandlers, andembed.ts:122still has no.catchonproviderPromise.No automated tests.
plugins/view-resourcesandplugins/text-editor-resourceshave no jest projects, and all three behaviours are DOM-level failure paths in Svelte components. Manual check for each: point the viewer at a blob id that does not resolve and confirm the "Failed to preview" label appears instead of a permanent spinner; give the embed node a URL whose provider match rejects and confirm the stub link renders.Note on scope
This was originally prepared together with an absolute-URL guard for
getPreviewThumbnailon the same read path. I have split that into a separate PR — it is a different concern, and it ships with unit tests whereas this one cannot.