fix(🐛): don't crash the web view when no WebGL surface can be created - #3996
Open
wildan-m wants to merge 1 commit into
Open
fix(🐛): don't crash the web view when no WebGL surface can be created#3996wildan-m wants to merge 1 commit into
wildan-m wants to merge 1 commit into
Conversation
On web, WebGLRenderer throws when WebGL is unavailable (hardware acceleration disabled, blocklisted GPU, or the per-page context limit exhausted). The constructor throw escapes the layout effect that builds the renderer, and the onResize throw escapes the ResizeObserver callback, where no try/catch or React error boundary can reach it - so an environment problem becomes an app crash. Degrade to an inert renderer instead: draw() and makeImageSnapshot() already no-op on a null surface, matching how StaticWebGLRenderer treats a failed surface as recoverable. A bubbling "skia-surface-unavailable" CustomEvent is dispatched on the canvas so embedders can show a fallback UI; without a listener it is a no-op.
Author
|
I have signed the CLA! |
43 tasks
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.
Description
On web,
WebGLRendererinSkiaPictureView.web.tsxthrows when the browser cannot provide a WebGL surface — hardware acceleration disabled, a blocklisted GPU, a GPU process restart, or the per-page live-context limit being exhausted. Both throw sites escape as uncatchable errors:useLayoutEffectthat builds the renderer, andonResizethrows inside theResizeObservercallback,so no
try/catchor React error boundary in the embedding app can reach them, and an environmental limitation becomes an app crash. We (Expensify) see this at scale in production Sentry asfailed to create webgl context: err 0/Could not create surfacefrom chart views on/homeand/search(Sentry issue APP-7MV: hundreds of users, thousands of events), currently worked around with apatch-packagepatch.Change
Degrade instead of throwing, mirroring how
StaticWebGLRendereralready treats a failed surface as recoverable rather than fatal:draw(),makeImageSnapshot()andonResizealready no-op on a nullsurface/grContext, anddispose()already handles the null fields.skia-surface-unavailableCustomEventon the canvas so embedders can detect the condition and show a fallback UI (deferred one frame so listeners attached in an effect of the same commit are registered first). Without a listener the event is a no-op, so existing consumers see no behavioral change other than not crashing.Notes
Test plan
HTMLCanvasElement.prototype.getContextreturnnullfor"webgl2": previously the uncaught throw surfaced and the canvas stayed blank; with this change the view mounts inert, the event fires on the canvas, and a listener can swap in fallback UI. Restoring WebGL and remounting renders normally.prettier --check(2.8.7) passes on the touched file.