Skip to content

Commit 8265441

Browse files
committed
feat: dont throw on ENOENT if allowMissing is set
1 parent abb5f5a commit 8265441

File tree

5 files changed

+24
-21
lines changed

5 files changed

+24
-21
lines changed

lib/fs.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2488,6 +2488,7 @@ function appendFileSync(path, data, options) {
24882488
* recursive?: boolean;
24892489
* encoding?: string;
24902490
* signal?: AbortSignal;
2491+
* throwIfNoEntry?: boolean;
24912492
* }} [options]
24922493
* @param {(
24932494
* eventType?: string,
@@ -2506,6 +2507,7 @@ function watch(filename, options, listener) {
25062507

25072508
if (options.persistent === undefined) options.persistent = true;
25082509
if (options.recursive === undefined) options.recursive = false;
2510+
if (options.throwIfNoEntry === undefined) options.throwIfNoEntry = true;
25092511

25102512
let watcher;
25112513
const watchers = require('internal/fs/watchers');
@@ -2523,7 +2525,8 @@ function watch(filename, options, listener) {
25232525
options.persistent,
25242526
options.recursive,
25252527
options.encoding,
2526-
options.ignore);
2528+
options.ignore,
2529+
options.throwIfNoEntry);
25272530
}
25282531

25292532
if (listener) {

lib/internal/fs/recursive_watch.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class FSWatcher extends EventEmitter {
5151

5252
assert(typeof options === 'object');
5353

54-
const { persistent, recursive, signal, encoding, ignore } = options;
54+
const { persistent, recursive, signal, encoding, ignore, throwIfNoEntry } = options;
5555

5656
// TODO(anonrig): Add non-recursive support to non-native-watcher for IBMi & AIX support.
5757
if (recursive != null) {
@@ -66,6 +66,10 @@ class FSWatcher extends EventEmitter {
6666
validateAbortSignal(signal, 'options.signal');
6767
}
6868

69+
if (throwIfNoEntry != null) {
70+
validateBoolean(throwIfNoEntry, 'options.throwIfNoEntry');
71+
}
72+
6973
if (encoding != null) {
7074
// This is required since on macOS and Windows it throws ERR_INVALID_ARG_VALUE
7175
if (typeof encoding !== 'string') {
@@ -76,7 +80,7 @@ class FSWatcher extends EventEmitter {
7680
validateIgnoreOption(ignore, 'options.ignore');
7781
this.#ignoreMatcher = createIgnoreMatcher(ignore);
7882

79-
this.#options = { persistent, recursive, signal, encoding };
83+
this.#options = { persistent, recursive, signal, encoding, throwIfNoEntry };
8084
}
8185

8286
close() {
@@ -222,7 +226,7 @@ class FSWatcher extends EventEmitter {
222226
this.#watchFolder(filename);
223227
}
224228
} catch (error) {
225-
if (error.code === 'ENOENT') {
229+
if (this.#options.throwIfNoEntry !== false && error.code === 'ENOENT') {
226230
error.filename = filename;
227231
throw error;
228232
}

lib/internal/fs/watchers.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const {
3535
} = internalBinding('fs');
3636

3737
const { FSEvent } = internalBinding('fs_event_wrap');
38-
const { UV_ENOSPC } = internalBinding('uv');
38+
const { UV_ENOSPC, UV_ENOENT } = internalBinding('uv');
3939
const { EventEmitter } = require('events');
4040

4141
const {
@@ -293,7 +293,8 @@ FSWatcher.prototype[kFSWatchStart] = function(filename,
293293
persistent,
294294
recursive,
295295
encoding,
296-
ignore) {
296+
ignore,
297+
throwIfNoEntry = true) {
297298
if (this._handle === null) { // closed
298299
return;
299300
}
@@ -313,6 +314,10 @@ FSWatcher.prototype[kFSWatchStart] = function(filename,
313314
recursive,
314315
encoding);
315316
if (err) {
317+
if (!throwIfNoEntry && err === UV_ENOENT) {
318+
return;
319+
}
320+
316321
const error = new UVException({
317322
errno: err,
318323
syscall: 'watch',

lib/internal/main/watch_mode.js

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,7 @@ function start() {
104104
ArrayPrototypeForEach(kEnvFiles, (file) => watcher.filterFile(resolve(file)));
105105
}
106106
if (kOptionalEnvFiles.length > 0) {
107-
ArrayPrototypeForEach(kOptionalEnvFiles, (file) => {
108-
try {
109-
watcher.filterFile(resolve(file));
110-
} catch (error) {
111-
if (error?.code !== 'ENOENT' && error?.code !== 'ENOTDIR') {
112-
throw error;
113-
}
114-
// Failed watching the file, ignore
115-
}
116-
});
107+
ArrayPrototypeForEach(kOptionalEnvFiles, (file) => watcher.filterFile(resolve(file), undefined, true));
117108
}
118109
child.once('exit', (code) => {
119110
exited = true;

lib/internal/watch_mode/files_watcher.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,11 @@ class FilesWatcher extends EventEmitter {
110110
return [...this.#watchers.keys()];
111111
}
112112

113-
watchPath(path, recursive = true) {
113+
watchPath(path, recursive = true, allowMissing = false) {
114114
if (this.#isPathWatched(path)) {
115115
return;
116116
}
117-
const watcher = watch(path, { recursive, signal: this.#signal });
117+
const watcher = watch(path, { recursive, signal: this.#signal, throwIfNoEntry: !allowMissing });
118118
watcher.on('change', (eventType, fileName) => {
119119
// `fileName` can be `null` if it cannot be determined. See
120120
// https://github.com/nodejs/node/pull/49891#issuecomment-1744673430.
@@ -126,14 +126,14 @@ class FilesWatcher extends EventEmitter {
126126
}
127127
}
128128

129-
filterFile(file, owner) {
129+
filterFile(file, owner, allowMissing = false) {
130130
if (!file) return;
131131
if (supportsRecursiveWatching) {
132-
this.watchPath(dirname(file));
132+
this.watchPath(dirname(file),true, allowMissing);
133133
} else {
134134
// Having multiple FSWatcher's seems to be slower
135135
// than a single recursive FSWatcher
136-
this.watchPath(file, false);
136+
this.watchPath(file, false, allowMissing);
137137
}
138138
this.#filteredFiles.add(file);
139139
if (owner) {

0 commit comments

Comments
 (0)