Skip to content

Commit 1e0c88a

Browse files
authored
fix: Handle ENOSPC error from chokidar (#2725)
* fix: Handle ENOSPC error from chokidar Now listens to the error event to check if "ENOSPC" occurrs. The watcher will then automaticly restart in polling mode, so that the user still sees his reqeusts / collections. Fixes: #1877 * Add more code comments, add !forcePolling to prevent endless loops and update error message
1 parent 29db85a commit 1e0c88a

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

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

+26-6
Original file line numberDiff line numberDiff line change
@@ -428,17 +428,16 @@ class Watcher {
428428
this.watchers = {};
429429
}
430430

431-
addWatcher(win, watchPath, collectionUid, brunoConfig) {
431+
addWatcher(win, watchPath, collectionUid, brunoConfig, forcePolling = false) {
432432
if (this.watchers[watchPath]) {
433433
this.watchers[watchPath].close();
434434
}
435435

436436
const ignores = brunoConfig?.ignore || [];
437-
const self = this;
438437
setTimeout(() => {
439438
const watcher = chokidar.watch(watchPath, {
440439
ignoreInitial: false,
441-
usePolling: watchPath.startsWith('\\\\') ? true : false,
440+
usePolling: watchPath.startsWith('\\\\') || forcePolling ? true : false,
442441
ignored: (filepath) => {
443442
const normalizedPath = filepath.replace(/\\/g, '/');
444443
const relativePath = path.relative(watchPath, normalizedPath);
@@ -457,14 +456,35 @@ class Watcher {
457456
depth: 20
458457
});
459458

459+
let startedNewWatcher = false;
460460
watcher
461461
.on('add', (pathname) => add(win, pathname, collectionUid, watchPath))
462462
.on('addDir', (pathname) => addDirectory(win, pathname, collectionUid, watchPath))
463463
.on('change', (pathname) => change(win, pathname, collectionUid, watchPath))
464464
.on('unlink', (pathname) => unlink(win, pathname, collectionUid, watchPath))
465-
.on('unlinkDir', (pathname) => unlinkDir(win, pathname, collectionUid, watchPath));
466-
467-
self.watchers[watchPath] = watcher;
465+
.on('unlinkDir', (pathname) => unlinkDir(win, pathname, collectionUid, watchPath))
466+
.on('error', (error) => {
467+
// `ENOSPC` stands for "Error No space" but is also thrown if the file watcher limit is reached.
468+
// To prevent loops `!forcePolling` is checked.
469+
if (error.code === 'ENOSPC' && !startedNewWatcher && !forcePolling) {
470+
// This callback is called for every file the watcher is trying to watch. To prevent a spam of messages and
471+
// Multiple watcher being started `startedNewWatcher` is set to prevent this.
472+
startedNewWatcher = true;
473+
watcher.close();
474+
console.error(
475+
`\nCould not start watcher for ${watchPath}:`,
476+
'ENOSPC: System limit for number of file watchers reached!',
477+
'Trying again with polling, this will be slower!\n',
478+
'Update you system config to allow more concurrently watched files with:',
479+
'"echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p"'
480+
);
481+
this.addWatcher(win, watchPath, collectionUid, brunoConfig, true);
482+
} else {
483+
console.error(`An error occurred in the watcher for: ${watchPath}`, error);
484+
}
485+
});
486+
487+
this.watchers[watchPath] = watcher;
468488
}, 100);
469489
}
470490

0 commit comments

Comments
 (0)