fix(runtime): render remote-server binary files (PDF/images) in the editor#6606
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/renderer/src/runtime/runtime-file-client.test.ts (1)
238-314: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd the non-previewable binary regression case.
The new tests cover previewable binaries and non-binary failures, but the PR contract also promises that non-previewable binaries still end up with the standard
binary_fileresult. A test wherefiles.readrejects withbinary_fileandfiles.readPreviewalso rejects would lock that behavior in.Suggested test shape
+ it('surfaces binary_file for non-previewable remote binaries', async () => { + runtimeEnvironmentCall.mockImplementation((args: { method: string }) => { + if (args.method === 'files.read') { + return Promise.resolve({ + id: 'rpc-read', + ok: false, + error: { code: 'runtime_error', message: 'binary_file' }, + _meta: { runtimeId: 'remote-runtime' } + }) + } + return Promise.resolve({ + id: 'rpc-preview', + ok: false, + error: { code: 'runtime_error', message: 'binary_file' }, + _meta: { runtimeId: 'remote-runtime' } + }) + }) + + await expect( + readRuntimeFileContent({ + settings: { activeRuntimeEnvironmentId: 'env-1' }, + filePath: '/remote/repo/archive.zip', + relativePath: 'archive.zip', + worktreeId: 'wt-1' + }) + ).rejects.toThrow('binary_file') + })
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: d324d008-df34-428c-9e84-b2b9a1d82093
📒 Files selected for processing (2)
src/renderer/src/runtime/runtime-file-client.test.tssrc/renderer/src/runtime/runtime-file-client.ts
Opening a binary file (PDF/image) on a remote-server runtime environment fell back to the text-only files.read RPC, which rejects binaries with 'binary_file' and dropped isImage/mimeType, so the editor never reached ImageViewer/PdfViewer. Fall back to the binary-capable files.readPreview RPC when files.read rejects a binary path, matching local/SSH behavior.
Scope the try/catch to the files.read call so the truncated-size guard is no
longer caught-and-rethrown, and match RuntimeRpcCallError('binary_file')
instead of any Error whose message text happens to equal 'binary_file'. Adds a
regression test that a non-RPC error sharing the message does not trigger the
preview fallback.
Co-authored-by: Orca <help@stably.ai>
cdd24f9 to
8c9b605
Compare
|
Thanks @amondnet for the clean, well-scoped fix and the thorough tests. A maintainer has taken over the PR, verified it end-to-end, rebased onto latest DescriptionBug: On a remote-server runtime environment, binary files (PDFs, images, etc.) never rendered in the editor — they showed a load error instead. They work fine locally and over SSH. Root cause: The editor loads content through Fix (author): When Maintainer hardening (this takeover):
EvidenceUnit is the practical harness here (full e2e needs a live remote-server runtime). Reproduced by reverting only the source fix while keeping the new tests: Before (fix reverted, tests kept) — the bug: The After (fix + hardening, rebased on ELI5When you opened a PDF or image while connected to a "remote server", the app asked for the file the wrong way — the server replied "that's a binary file, I won't hand it over like text," and the app just showed an error. Now, when the app hears "that's binary," it re-asks using the request built for binaries, gets the picture/PDF back, and shows it — the same way it already worked on your own machine. Trade-offsNo regressions. Behavior is unchanged for every other case: text files still read normally, oversized text still hits the "too large to open" guard, and non- Not merging — leaving the final call to a human maintainer. |
|
Thanks @amondnet and sorry for delay! |
…fix garbled comments (#7322) Quality pass on renderer/shared PRs merged 2026-07-03: - WorktreeTitleInlineRename: skip the truncation measure + ResizeObserver in `wrapTitle` mode, where wrapped titles never truncate — it could only churn unused state (#7307). - editor slice: reuse the `removeEditorStateForReplacedPreview` helper this PR added instead of a hand-rolled copy of the same six-field eviction (drops ~50 lines) (#6476). - useFileExplorerTree: extract `readWorktreeDirectory` so the connectionId/settings assembly for `readRuntimeDirectory` lives in one place, not three (#6321). - comment-markdown-github-attachment-media: extract a shared `AttachmentFallbackLink` for the image/video error-fallback link (#6759). - repository-icon-github: fold the two near-identical live resolvers into one parameterized `resolveRepositoryIdentityLive`; trim a 3-line comment to 2 (#6507). - resource-usage-open-slices: delete the `shouldReadPopoverSlices` identity wrapper and inline `open` at the four call sites (#7275). - BrowserPane: drop the pointerEvents assignment already applied inside `ensureBrowserPageWebview` for the reused-webview path (#6958). - github slice: fix two garbled "…a commit main confirmed…" comments (#7277). - runtime-file-client: trim the binary-file fallback comment to its whys (#6606). - composer-branch-selection: drop the inline comment that restated the JSDoc (#6748). - TabBarQuickCommandsButton: correct the stale "+ Command" comment (button shows no +). No behavior change (the editor-helper reuse is behavior-equivalent, only more conservative on an edge case); typecheck, oxlint, react-doctor, oxfmt, and touched unit suites all pass.
Summary
Binary files (PDF, images) failed to render in the editor when connected to a remote-server runtime environment (the feature labeled "remote server" in the UI). They render fine locally and over SSH.
Root cause
The editor loads file content through
readRuntimeFileContent(src/renderer/src/runtime/runtime-file-client.ts). Routing differs per target:window.api.fs.readFile(...)returns full binary metadata{ content (base64), isBinary, isImage, mimeType }→ PDFs/images render.files.readRPC →readMobileFile, which throwsbinary_filefor previewable binaries (.pdf/images are inMOBILE_BINARY_EXTENSIONS) and the client hardcodedisBinary: false. The error became aloadError, so the file never reachedImageViewer/PdfViewer.A sibling RPC already does the right thing:
files.readPreview→readFileExplorerPreviewreturns{ content (base64), isBinary, isImage, mimeType }for local, SSH, and environment runtimes.Fix
When
files.readrejects a binary path withbinary_file, fall back to the binary-capablefiles.readPreviewRPC and return its payload. This keeps the server as the single source of truth for binary detection (no duplicated extension list) and reuses the existing preview path — matching local/SSH behavior.Non-previewable binaries (e.g.
.zip,.mp4) now show the clean "Binary file — cannot display" message instead of a load error. Text editing is unchanged.Test plan
runtime-file-client.test.ts: added a case asserting a remote binary read falls back tofiles.readPreview, and a case asserting non-binary_fileerrors do not fall back. All 38 tests pass.typecheck:webclean,oxlintclean on changed files..pdfand.png(render), a.zip(clean binary message), and a text file (still editable).