Skip to content

Commit 16d5404

Browse files
committed
fix: close file watchers before app exit to prevent crash on macOS
Close all chokidar file watchers (collection, workspace, apiSpec) before the Node environment is torn down. The native FSEvents watchers run on their own threads and their cleanup races with FreeEnvironment, causing an abort when fse_instance_destroy tries to lock a destroyed mutex. Watchers are closed in both mainWindow.on('close') and app.on('before-quit') to cover the native close button path and the app.exit() path.
1 parent 90fb7c8 commit 16d5404

File tree

4 files changed

+20
-26
lines changed

4 files changed

+20
-26
lines changed

packages/bruno-electron/src/app/apiSpecsWatcher.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,9 @@ class ApiSpecWatcher {
144144

145145
closeAllWatchers() {
146146
for (const [watchPath, watcher] of Object.entries(this.watchers)) {
147-
if (watcher) {
148-
try {
149-
watcher.close();
150-
} catch (err) {}
151-
}
147+
try {
148+
watcher?.close();
149+
} catch (err) {}
152150
}
153151
this.watchers = {};
154152
this.watcherWorkspaces = {};

packages/bruno-electron/src/app/collection-watcher.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -961,11 +961,9 @@ class CollectionWatcher {
961961

962962
closeAllWatchers() {
963963
for (const [watchPath, watcher] of Object.entries(this.watchers)) {
964-
if (watcher) {
965-
try {
966-
watcher.close();
967-
} catch (err) {}
968-
}
964+
try {
965+
watcher?.close();
966+
} catch (err) {}
969967
}
970968
this.watchers = {};
971969
}

packages/bruno-electron/src/app/workspace-watcher.js

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -227,20 +227,16 @@ class WorkspaceWatcher {
227227

228228
closeAllWatchers() {
229229
for (const [watchPath, watcher] of Object.entries(this.watchers)) {
230-
if (watcher) {
231-
try {
232-
watcher.close();
233-
} catch (err) {}
234-
}
230+
try {
231+
watcher?.close();
232+
} catch (err) {}
235233
}
236234
this.watchers = {};
237235

238236
for (const [watchPath, watcher] of Object.entries(this.environmentWatchers)) {
239-
if (watcher) {
240-
try {
241-
watcher.close();
242-
} catch (err) {}
243-
}
237+
try {
238+
watcher?.close();
239+
} catch (err) {}
244240
}
245241
this.environmentWatchers = {};
246242

packages/bruno-electron/src/index.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ const focusMainWindow = () => {
122122
}
123123
};
124124

125+
const closeAllWatchers = () => {
126+
collectionWatcher.closeAllWatchers();
127+
workspaceWatcher.closeAllWatchers();
128+
apiSpecWatcher.closeAllWatchers();
129+
};
130+
125131
// Parse protocol URL from command line arguments (if any)
126132
appProtocolUrl = getAppProtocolUrlFromArgv(process.argv);
127133

@@ -387,9 +393,7 @@ app.on('ready', async () => {
387393

388394
mainWindow.on('close', (e) => {
389395
e.preventDefault();
390-
collectionWatcher.closeAllWatchers();
391-
workspaceWatcher.closeAllWatchers();
392-
apiSpecWatcher.closeAllWatchers();
396+
closeAllWatchers();
393397
terminalManager.cleanup(mainWindow.webContents);
394398
ipcMain.emit('main:start-quit-flow');
395399
});
@@ -462,9 +466,7 @@ app.on('ready', async () => {
462466

463467
// Quit the app once all windows are closed
464468
app.on('before-quit', () => {
465-
collectionWatcher.closeAllWatchers();
466-
workspaceWatcher.closeAllWatchers();
467-
apiSpecWatcher.closeAllWatchers();
469+
closeAllWatchers();
468470
// Release single instance lock to allow other instances to take over
469471
if (useSingleInstance && gotTheLock) {
470472
app.releaseSingleInstanceLock();

0 commit comments

Comments
 (0)