Skip to content

Commit f34e706

Browse files
committed
🤖 fix: prevent IPC send to destroyed window
Add isDestroyed() checks before all mainWindow.webContents.send() calls to prevent 'Object has been destroyed' errors when the window is closed while background processes (like init stderr streams) are still emitting events. Fixes crash when closing window during workspace initialization.
1 parent d06a4a2 commit f34e706

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

src/node/services/ipcMain.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ export class IpcMain {
228228
workspaceId: string,
229229
snapshot: WorkspaceActivitySnapshot | null
230230
): void {
231-
if (!this.mainWindow) {
231+
if (!this.mainWindow || this.mainWindow.isDestroyed()) {
232232
return;
233233
}
234234
this.mainWindow.webContents.send(IPC_CHANNELS.WORKSPACE_ACTIVITY, {
@@ -508,15 +508,15 @@ export class IpcMain {
508508
});
509509

510510
const chatUnsubscribe = session.onChatEvent((event) => {
511-
if (!this.mainWindow) {
511+
if (!this.mainWindow || this.mainWindow.isDestroyed()) {
512512
return;
513513
}
514514
const channel = getChatChannel(event.workspaceId);
515515
this.mainWindow.webContents.send(channel, event.message);
516516
});
517517

518518
const metadataUnsubscribe = session.onMetadataEvent((event) => {
519-
if (!this.mainWindow) {
519+
if (!this.mainWindow || this.mainWindow.isDestroyed()) {
520520
return;
521521
}
522522
this.mainWindow.webContents.send(IPC_CHANNELS.WORKSPACE_METADATA, {
@@ -969,7 +969,7 @@ export class IpcMain {
969969
const session = this.sessions.get(workspaceId);
970970
if (session) {
971971
session.emitMetadata(updatedMetadata);
972-
} else if (this.mainWindow) {
972+
} else if (this.mainWindow && !this.mainWindow.isDestroyed()) {
973973
this.mainWindow.webContents.send(IPC_CHANNELS.WORKSPACE_METADATA, {
974974
workspaceId,
975975
metadata: updatedMetadata,
@@ -1379,7 +1379,9 @@ export class IpcMain {
13791379
type: "delete",
13801380
historySequences: deletedSequences,
13811381
};
1382-
this.mainWindow.webContents.send(getChatChannel(workspaceId), deleteMessage);
1382+
if (this.mainWindow && !this.mainWindow.isDestroyed()) {
1383+
this.mainWindow.webContents.send(getChatChannel(workspaceId), deleteMessage);
1384+
}
13831385
}
13841386

13851387
return { success: true, data: undefined };
@@ -1417,7 +1419,7 @@ export class IpcMain {
14171419
}
14181420

14191421
// Send delete event to frontend for all old messages
1420-
if (deletedSequences.length > 0 && this.mainWindow) {
1422+
if (deletedSequences.length > 0 && this.mainWindow && !this.mainWindow.isDestroyed()) {
14211423
const deleteMessage: DeleteMessage = {
14221424
type: "delete",
14231425
historySequences: deletedSequences,
@@ -1426,7 +1428,7 @@ export class IpcMain {
14261428
}
14271429

14281430
// Send the new summary message to frontend
1429-
if (this.mainWindow) {
1431+
if (this.mainWindow && !this.mainWindow.isDestroyed()) {
14301432
this.mainWindow.webContents.send(getChatChannel(workspaceId), summaryMessage);
14311433
}
14321434

@@ -1632,7 +1634,7 @@ export class IpcMain {
16321634
const existingSession = this.sessions.get(workspaceId);
16331635
if (existingSession) {
16341636
existingSession.emitMetadata(null);
1635-
} else if (this.mainWindow) {
1637+
} else if (this.mainWindow && !this.mainWindow.isDestroyed()) {
16361638
this.mainWindow.webContents.send(IPC_CHANNELS.WORKSPACE_METADATA, {
16371639
workspaceId,
16381640
metadata: null,
@@ -2091,7 +2093,7 @@ export class IpcMain {
20912093
const chatChannel = getChatChannel(workspaceId);
20922094

20932095
await session.replayHistory((event) => {
2094-
if (!this.mainWindow) {
2096+
if (!this.mainWindow || this.mainWindow.isDestroyed()) {
20952097
return;
20962098
}
20972099
this.mainWindow.webContents.send(chatChannel, event.message);

0 commit comments

Comments
 (0)