diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown index bb90cc8d2e3f4e..985a4e4c967a0f 100644 --- a/doc/api/fs.markdown +++ b/doc/api/fs.markdown @@ -576,6 +576,9 @@ These stat objects are instances of `fs.Stat`. If you want to be notified when the file was modified, not just accessed you need to compare `curr.mtime` and `prev.mtime`. +_Note: when an `fs.watchFile` operation results in an `ENOENT` error, it will +invoke the callback once. This is a change in functionality since v0.10._ + _Note: `fs.watch` is more efficient than `fs.watchFile` and `fs.unwatchFile`. `fs.watch` should be used instead of `fs.watchFile` and `fs.unwatchFile` when possible._ diff --git a/lib/fs.js b/lib/fs.js index 58704e529747b2..9c13a82c41e5b1 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1305,13 +1305,12 @@ StatWatcher.prototype.stop = function() { const statWatchers = new Map(); -fs.watchFile = function(filename) { +fs.watchFile = function(filename, options, listener) { nullCheck(filename); filename = pathModule.resolve(filename); var stat; - var listener; - var options = { + var defaults = { // Poll interval in milliseconds. 5007 is what libev used to use. It's // a little on the slow side but let's stick with it for now to keep // behavioral changes to a minimum. @@ -1319,14 +1318,14 @@ fs.watchFile = function(filename) { persistent: true }; - if (arguments[1] !== null && typeof arguments[1] === 'object') { - options = util._extend(options, arguments[1]); - listener = arguments[2]; + if (options !== null && typeof options === 'object') { + options = util._extend(defaults, options); } else { - listener = arguments[1]; + listener = options; + options = defaults; } - if (!listener) { + if (typeof listener !== 'function') { throw new Error('watchFile requires a listener function'); } diff --git a/test/parallel/test-fs-watchfile.js b/test/parallel/test-fs-watchfile.js new file mode 100644 index 00000000000000..eacb2f9d821982 --- /dev/null +++ b/test/parallel/test-fs-watchfile.js @@ -0,0 +1,26 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const assert = require('assert'); +const common = require('../common'); +const fixtures = path.join(__dirname, '..', 'fixtures'); + +// Basic usage tests. +assert.throws(function() { + fs.watchFile('./some-file'); +}, /watchFile requires a listener function/); + +assert.throws(function() { + fs.watchFile('./another-file', {}, 'bad listener'); +}, /watchFile requires a listener function/); + +assert.throws(function() { + fs.watchFile(new Object(), function() {}); +}, /Path must be a string/); + +// Test ENOENT. Should fire once. +const enoentFile = path.join(fixtures, 'empty', 'non-existent-file'); +fs.watchFile(enoentFile, common.mustCall(function(curr, prev) { + fs.unwatchFile(enoentFile); +}));