diff --git a/lib/internal/fs/recursive_watch.js b/lib/internal/fs/recursive_watch.js index ad12afc9a8f755..ec738536db6deb 100644 --- a/lib/internal/fs/recursive_watch.js +++ b/lib/internal/fs/recursive_watch.js @@ -157,7 +157,9 @@ class FSWatcher extends EventEmitter { } } } catch (error) { - this.emit('error', error); + if (error.code !== 'ENOENT') { + this.emit('error', error); + } } } diff --git a/test/parallel/test-fs-watch-recursive-delete-race.js b/test/parallel/test-fs-watch-recursive-delete-race.js new file mode 100644 index 00000000000000..f60668197c57cd --- /dev/null +++ b/test/parallel/test-fs-watch-recursive-delete-race.js @@ -0,0 +1,44 @@ +// Flags: --expose-internals +'use strict'; + +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); +const { kFSWatchStart } = require('internal/fs/watchers'); +const { FSWatcher } = require('internal/fs/recursive_watch'); + +if (common.isIBMi) + common.skip('IBMi does not support `fs.watch()`'); + +tmpdir.refresh(); + +const parent = tmpdir.resolve('parent'); +const child = path.join(parent, 'child'); +fs.mkdirSync(child, { recursive: true }); +fs.writeFileSync(path.join(child, 'test.tmp'), 'test'); + +const watch = fs.watch; +let deletedChild = false; +fs.watch = function(filename, ...args) { + const watcher = Reflect.apply(watch, this, [filename, ...args]); + + if (filename === child) { + fs.rmSync(child, { recursive: true }); + deletedChild = true; + } + + return watcher; +}; + +const watcher = new FSWatcher({ recursive: true }); +watcher.on('error', common.mustNotCall()); + +try { + watcher[kFSWatchStart](parent); + assert.strictEqual(deletedChild, true); +} finally { + watcher.close(); + fs.watch = watch; +}