fix: surface Rust compositor panics to error tracking - #29
Draft
posthog[bot] wants to merge 3 commits into
Draft
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
|
All contributors have signed the CLA ✍️ ✅ |
A Rust panic in the WASM compositor traps as a stackless `RuntimeError: unreachable`, reaching error tracking with no message or source location. - Replace the console-only panic hook with a custom `std::panic::set_hook` that records the panic payload + Rust file:line into a thread-local, exposed to JS via a `take_last_panic()` export. - Have the compositor worker recover that message and rethrow an enriched `CompositorCrashedError`, and report (rather than silently swallow) crashes in the void-returning entry points (resize/loadFont/uploadBitmap/uploadLut/ flush and siblings). - Harden the specific unguarded unwraps that can panic into proper `CompositorError` returns. Generated-By: PostHog Code Task-Id: 14f4c22c-05c7-4b6c-b385-a67bdaf5e537
… dep Cargo.toml already dropped the dependency; Cargo.lock wasn't updated to match because the PR author couldn't run the Rust toolchain locally.
mohebifar
added a commit
that referenced
this pull request
Aug 3, 2026
PostHog's autonomous bug-fixing agent (PR #29) opens PRs from the same posthog[bot] GitHub App identity every time, and can't itself click through the CLA signing flow. Allowlisting it alongside the other bot committers (dependabot, renovate, github-actions) unblocks the cla check on that PR and any future ones from the same integration.
resize() worker-side used to swallow a crash silently (markCrashed without rethrowing) — this PR's whole point is to stop that, and it now correctly rethrows like every other entry point. But compositor-api.ts's resize() wrapper fire-and-forgets its call (void enqueue(...), no caller awaits a resize) and had no .catch, so a crash during resize would surface as an unhandled promise rejection in the console — the crash itself still gets reported correctly via reportCrash()/onCrash() (reportingCall does that before rethrowing), this was purely a stray rejection on top of that.
mohebifar
force-pushed
the
posthog-self-driving/fixcompositor-surface-rust-panic-3d8545
branch
from
August 3, 2026 00:41
23fbf7c to
0c9db75
Compare
Owner
|
Reviewed and addressed the open items from review:
Verified end-to-end after these changes:
|
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
RuntimeError: unreachable— no message, no source location — so we can't tell which panic fired. Diagnosability hole in the core rendering path; it blocks triage of the whole class of WASM crashes.crashed = true, permanently disabling the preview for the rest of that editing session.resize,loadFont,uploadBitmap,uploadLut,flush, and siblings) callmarkCrashedwithout rethrowing, so those panics never cross the comlink boundary and are never reported at all — the true crash rate may be higher than what we see.Changes
console_error_panic_hookwith a customstd::panic::set_hookthat records each panic's payload + Rustfile:line:colinto a thread-local (still logging to console), exposed to JS as atake_last_panic()export /takeLastCompositorPanic()helper. Reading it is safe after a trap — it only touches a thread-local, not GPU state.CompositorCrashedErrorwhose message carries the real Rust location. Every entry point now rethrows on its first failure; later calls short-circuit on the crash latch, so at most one error is surfaced per crash.CompositorErrorreturns / panic-free matches instead ofunwrap():compositor.rsensure_render_textureis_none() || unwrap()→matchcompositor.rsrender_frame_to_pixelsrender_texture/readback_bufferunwrap()→RenderStateNotInitializedtexture.rsupload_bitmaptextures.get().unwrap()→TextureNotFoundtext.rsunwrap()Risk
Testing
pnpm --filter @tooscut/render-engine test(135 passing) and oxlint on the changed TS. The Rust/WASM build requires the toolchain (not available in this environment); the Rust changes are mechanical (unwrap()→?/match, new panic hook) and compile-checked by CI.Agent context
/assets) is unrelated.renderFramealready did) is what got the one observed event into error tracking, so extending that to the swallowing paths is the minimal, consistent fix.Created with PostHog Desktop from this inbox report.