Skip to content

fix: do not break app startup on an Electron without registerPreloadScript - #27

Merged
Fiona2016 merged 3 commits into
publishfrom
fix/legacy-electron-preload-crash
Sep 3, 2026
Merged

Fiona2016 merged 3 commits into
publishfrom
fix/legacy-electron-preload-crash

Conversation

@Fiona2016

@Fiona2016 Fiona2016 commented Sep 3, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

session.registerPreloadScript was added in Electron 35. The SDK registers the bridge preload through it from an app 'ready' listener and from 'session-created' — neither of which the host application can guard — so on an older runtime the missing method threw where nothing could catch it.

The instrumentation entry point runs before the application's own 'ready' handler, so the failure preempted window creation: the application died at startup with

TypeError: Cannot read properties of undefined (reading 'bind')

which says nothing about the Electron version behind it.

peerDependencies: electron >= 39 does not prevent this. It is an installation error only under npm; Yarn and pnpm merely warn and install.

(dd-trace registers a preload of its own the same way, but datadog-instrumentations gates its whole Electron hook on electron >= 37, so on the versions this is about it installs nothing.)

Change

  • Install a stand-in for the missing method at the session boundary, before anything reads it.
  • Warn once, naming the cause and what it costs.
  • Wrap the listeners the SDK puts on the host application in monitor(), at setUp's definition, so no failure inside them can propagate into the application again.

An unsupported Electron now loses the renderer bridge instead of the application: main process monitoring is unaffected, and the Browser SDK keeps collecting in renderers, though renderer events do not share the main process session.

Verification

  • New unit cases drive the real installBridgePreload with a session shaped like Electron < 35 (no registerPreloadScript). Reverting the source change makes all five fail with the exact TypeError above.
  • Covered: the deferred 'ready' path, the session-created path, the isReady()-true path, a subsequent registration through the patched method, and warn-once across sessions.
  • Full unit suite (696 tests), tsc --noEmit and eslint clean; CI green.

…cript

`session.registerPreloadScript` was added in Electron 35. Both this SDK and
dd-trace's `BrowserWindow` subclass call it unconditionally -- the SDK from an
`app` 'ready' listener, dd-trace from every `new BrowserWindow()` -- so on an
older runtime the missing method threw where the host application had no way to
catch it. The instrumentation entry point runs before the application's own
'ready' handler, so the failure preempted window creation and the application
died at startup with `Cannot read properties of undefined (reading 'bind')`.

`peerDependencies: electron >= 39` does not prevent this: it is an installation
error only under npm, and a warning under Yarn and pnpm.

Install a stand-in for the missing method at the session boundary, before
anything reads it, so dd-trace's call is harmless too, and warn once with the
cause. Losing the renderer bridge is what an unsupported Electron costs: main
process monitoring is unaffected and the Browser SDK keeps collecting in
renderers, though renderer events do not share the main process session.

Also wrap the listeners the SDK puts on the host application in `monitor()`, so
no failure inside them can propagate into the application again.
…ion site

Both listeners the SDK registers on the host application end up in `setUp`, so
wrapping it once covers the 'session-created' event, the deferred 'ready'
listener and the synchronous `isReady()` branch alike. This is also how the rest
of the SDK guards its listeners -- at the definition, not per registration.
`datadog-instrumentations` gates its whole Electron hook on `electron >= 37`,
so dd-trace never wraps `BrowserWindow` — and never registers a preload — on the
versions this failure is about. The startup failure came from the SDK's own
listeners alone; the stand-in and the `monitor()` wrappers are unchanged.
@Fiona2016
Fiona2016 merged commit 3e7faba into publish Sep 3, 2026
2 checks passed
@Fiona2016
Fiona2016 deleted the fix/legacy-electron-preload-crash branch September 3, 2026 11:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant