fix: harden startup and keybinding paths against errors seen in alpha.38 - #104
Merged
Merged
Conversation
Fixes the five real issues reported by Sentry against 0.1.0-alpha.38 in the first hours of telemetry from real users. Splash screen (EDITOR-2, `TypeError: Object has been destroyed`) The `maxDuration` timer outlives the windows it closes. Quitting during startup destroys both windows, and `splashScreenWindow.close()` — or `mainWindow.isVisible()` on the same path — then throws. Guard both with `isDestroyed()`. Monaco keybinding dispatch (EDITOR-4, EDITOR-6, `Cannot read properties of undefined (reading 'keyCode')`) `KeyCode.createKeyCode` deliberately leaves `key` unset for modifier-only chords, so the `keyCode.key!` assertion in `toKeybinding` is not sound. Return `undefined` there and let `getDispatchChords` emit `null`, which its signature already allows — matching how `getSingleModifierDispatchPart` right above it already handles the same case. Keybinding registry (EDITOR-5, `Cannot get key code from the keyboard event`) Some layouts and IMEs deliver events with no usable `code`, `keyCode` or `keyIdentifier`. `KeyCode.createKeyCode` throws on those, and `KeybindingRegistry.run` is called straight from a `keydown` listener, so the error escapes unhandled. No keybinding can match such an event; drop it. Toolbar storage (EDITOR-3, `A resource provider for 'user-storage:/user/toolbar.json' is not registered`) `@postConstruct init()` left `doInit()` floating, so a failure to resolve the config surfaced as an unhandled rejection. Handle it — the toolbar already falls back to its defaults. `DefaultResourceProvider.get` also swallowed every resolver error before reporting that nothing handled the URI, which is why the report says nothing about the underlying cause; attach them as the error's `cause` so the next occurrence is diagnosable.
The spec's module-level JSDOM is torn down before these cases run, so tests that construct DOM objects re-enable it locally. The new test did not, and failed with `ReferenceError: KeyboardEvent is not defined`.
This was referenced Aug 20, 2026
dubadub
added a commit
that referenced
this pull request
Aug 20, 2026
PR #104's first run was killed at 6h0m14s, GitHub's default job limit. It had hung in `apt-get update`: all four azure.archive.ubuntu.com entries were `Ign`'d, the fallback to archive.ubuntu.com stalled mid-fetch, and the job sat there for six hours before reporting anything. A green run takes ~10 minutes. Adds a 45m job timeout (generous headroom over a cold-cache run) and a 10m timeout on the apt step itself, which is the step actually observed to hang. A stall now surfaces in minutes instead of occupying a runner for six hours.
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.
Fixes the five real issues Sentry reported against
0.1.0-alpha.38in the first hours of telemetry from real users. All were unhandled errors, none crashed the app.TypeError: Object has been destroyedA resource provider for 'user-storage:/user/toolbar.json' is not registeredCannot read properties of undefined (reading 'keyCode')Cannot get key code from the keyboard eventSplash screen — EDITOR-2
The
maxDurationtimer outlives the windows it closes. Quitting during startup destroys both windows, andsplashScreenWindow.close()then throws. Guarded withisDestroyed()— includingmainWindow.isVisible()on the same path, which fails the same way; the reported frame was just whichever ran first.Monaco keybinding dispatch — EDITOR-4 / EDITOR-6
KeyCode.createKeyCodedeliberately leaveskeyunset for modifier-only chords, so thekeyCode.key!assertion intoKeybindingis not sound. It now returnsundefinedandgetDispatchChordsemitsnull, which its(string | null)[]signature already allows — the same handlinggetSingleModifierDispatchPartdirectly above it already applies to this case.Keybinding registry — EDITOR-5
Some layouts and IMEs deliver events with no usable
code,keyCodeorkeyIdentifier.KeyCode.createKeyCodethrows on those, andKebindingRegistry.runis called straight from akeydownlistener, so the error escapes unhandled. No keybinding can match such an event, so it is dropped. Both EDITOR-5 and EDITOR-4/6 came from one user in France on Windows 10 within the same second — likely one keypress hitting two listeners.Toolbar storage — EDITOR-3
@postConstruct init()leftdoInit()floating, so a failure to resolve the config surfaced as an unhandled rejection; it is now handled (the toolbar already falls back to its defaults).DefaultResourceProvider.getalso swallowed every resolver error before reporting that nothing handled the URI — which is why the Sentry report says nothing about the underlying cause. They are now attached as the error'scause.This is the part I am least confident about. The catch makes the symptom benign and the next occurrence diagnosable, but it does not fix why the
user-storage:provider was unavailable at that moment. That needs the cause data this PR adds.Verification
lerna run compilepasses for@theia/core,@theia/monaco,@theia/toolbar;eslintclean on all touched files.key === undefined, and an event with no usablecode/keyCodethrows out ofcreateKeyCode.keybinding.spec.tsfor the unmappable-event case.The splash-screen and toolbar fixes are defensive guards validated by inspection; neither race was reproduced locally.