electron / electron/devtron

IPC handlers registered before devtron.install() receive wrapped payloads instead of original arguments

Open
#314 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
1.8k
Forks
110
Avg merge
1h 54m
Merged PRs (30d)
7

Description

### Describe the bug

When `devtron.install()` is called after other libraries have already registered IPC handlers via `ipcMain.handle()`, those pre-existing handlers receive devtron's wrapped payload object `{ __uuid__devtron, args }` instead of the original arguments.

This is because:

1. Devtron's `patchIpcMain()` replaces `ipcMain.handle` with a wrapper that calls `getArgsFromPayload()` to unwrap arguments
2. However, handlers registered **before** `patchIpcMain()` was called are using the original `ipcMain.handle`, so they never go through the unwrapping logic
3. Meanwhile, devtron's renderer-preload **always** wraps `ipcRenderer.invoke` calls with the `{ __uuid__devtron, args }` payload format

### To Reproduce

1. Register an IPC handler before devtron is installed:

```javascript
// Early in app initialization
ipcMain.handle('my-channel', (event, methodName, ...args) => {
console.log('methodName:', methodName); // Expects a string like 'doSomething'
});

2. Install devtron later (e.g., after app.whenReady()):
app.whenReady().then(async () => {
const { devtron } = await import('@electron/devtron');
await devtron.install();
});

3. From the renderer, invoke the channel:
ipcRenderer.invoke('my-channel', 'doSomething', { data: 'test' });

4. Expected: methodName is 'doSomething'
5. Actual: methodName is { __uuid__devtron: '...', args: ['doSomething', { data: 'test' }] }
```

Real-world example

This breaks @bugsnag/electron which registers IPC handlers during module initialization (before devtron can be installed). When calling bugsnag.notify() from the renderer, the main process logs:

`[BUGSNAG] attempted to call IPC method named "[object Object]" which doesn't exist`

And Bugsnag is initialized before everything else in an Electron app, to catch as many as possible bugs.

### Suggested solutions

1. Patch existing handlers - When patchIpcMain() is called, retroactively wrap any handlers that were already registered with the unwrapping logic.

OR

2. Channel exclusion list - Allow users to specify channels that should be excluded from devtron's payload wrapping:
devtron.install({
excludeChannels: ['bugsnag::renderer-to-main', 'bugsnag::renderer-to-main-sync']
});

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.