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:
- Devtron's
patchIpcMain() replaces ipcMain.handle with a wrapper that calls getArgsFromPayload() to unwrap arguments - However, handlers registered before
patchIpcMain() was called are using the original ipcMain.handle, so they never go through the unwrapping logic - Meanwhile, devtron's renderer-preload always wraps
ipcRenderer.invoke calls with the { __uuid__devtron, args } payload format
To Reproduce
- Register an IPC handler before devtron is installed:
// Early in app initializationipcMain.handle('my-channel',(event,methodName, ...args)=>{console.log('methodName:',methodName);// Expects a string like 'doSomething'});2.Installdevtronlater(e.g.,afterapp.whenReady()):
app.whenReady().then(async()=>{const{ devtron }=awaitimport('@electron/devtron');awaitdevtron.install();});3.Fromtherenderer,invokethechannel:
ipcRenderer.invoke('my-channel','doSomething',{data: 'test'});4. Expected: methodNameis'doSomething'5. Actual: methodNameis{__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
- Patch existing handlers - When patchIpcMain() is called, retroactively wrap any handlers that were already registered with the unwrapping logic.
OR
- 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']
});
Describe the bug
When
devtron.install()is called after other libraries have already registered IPC handlers viaipcMain.handle(), those pre-existing handlers receive devtron's wrapped payload object{ __uuid__devtron, args }instead of the original arguments.This is because:
patchIpcMain()replacesipcMain.handlewith a wrapper that callsgetArgsFromPayload()to unwrap argumentspatchIpcMain()was called are using the originalipcMain.handle, so they never go through the unwrapping logicipcRenderer.invokecalls with the{ __uuid__devtron, args }payload formatTo Reproduce
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 existAnd Bugsnag is initialized before everything else in an Electron app, to catch as many as possible bugs.
Suggested solutions
OR
devtron.install({
excludeChannels: ['bugsnag::renderer-to-main', 'bugsnag::renderer-to-main-sync']
});