Otis Wright
Otis Wright

Reputation: 2110

Nodejs fs | Error: ENOTDIR: not a directory

So I am using a third party project and there is the following code block:

// walk through /run and remove all filecontents, keeping 1 level directories.
var root = '/run';

if (fs.existsSync(root)) {
  fs.readdirSync(root).forEach(cleanFileOrDir);
}

where cleanFileOrDir is:

function cleanFileOrDir(f) {
  var fPath = path.join(root, f);
  if (fs.statSync(fPath).isFile()) {
    // if its a file delete it right away
    rimraf.sync(fPath);
  } else {
    // remove its contents
    rimrafKidsSync(fPath);
  }
}

I am receiving the following error:

fs.js:945
  return binding.readdir(pathModule._makeLong(path), options.encoding);
                 ^

Error: ENOTDIR: not a directory, scandir '/run/acpid.socket'
    at Error (native)
    at Object.fs.readdirSync (fs.js:945:18)
    at rimrafKidsSync (/home/otis/Developer/project/dockworker/lib/controllers/dockCleaner.js:27:6)
    at cleanFileOrDir (/home/otis/Developer/project/dockworker/lib/controllers/dockCleaner.js:22:5)
    at Array.forEach (native)
    at Object.<anonymous> (/home/otis/Developer/project/dockworker/lib/controllers/dockCleaner.js:8:24)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)

And the contents of my /run/ directory are:

acpid.socket   crond.pid          docker       irqbalance.pid  mlocate.daily.lock  pppconfig        snapd.socket  udev     wpa_supplicant
agetty.reload  crond.reboot       docker.pid   lightdm         mount               resolvconf       sudo          udisks2  xtables.lock
alsa           cups               docker.sock  lightdm.pid     network             rsyslogd.pid     systemd       user
avahi-daemon   dbus               initctl      lock            NetworkManager      sendsigs.omit.d  thermald      utmp
containerd     dhclient-wlo1.pid  initramfs    log             plymouth            shm              tmpfiles.d    uuidd

I think this may have been an issue introduced by Nodejs v6 the file system may have changed?

Update I modified the cleanFileOrDir function to look like this:

function cleanFileOrDir(f) {
  var fPath = path.join(root, f);
  console.log(fPath);
  if (fs.statSync(fPath).isFile()) {
    // if its a file delete it right away
    console.log('Is file');
    rimraf.sync(fPath);
  } else {
    // remove its contents
    console.log('Is directory');
    rimrafKidsSync(fPath);
  }
}

I now get the following output:

/run/NetworkManager
Is directory
/run/acpid.socket
Is directory
fs.js:945

So in short it is treating /run/acpid.socket as a directory, any idea's why this would be?

Upvotes: 2

Views: 23712

Answers (1)

stdob--
stdob--

Reputation: 29167

Since "aspid.socket" - a socket, it is not a regular file and it is not a directory. List of available tests:

stats.isFile()
stats.isDirectory()
stats.isBlockDevice()
stats.isCharacterDevice()
stats.isFIFO()
stats.isSocket()

So you need to change the logic:

function cleanFileOrDir(f) {
  var fPath = path.join(root, f);
  var stat = fs.statSync(fPath);

  if (stat.isFile()) {
    // if its a file delete it right away
    rimraf.sync(fPath);
  } else 
  if (stat.isDirectory()){
    // remove its contents
    rimrafKidsSync(fPath);
  } else
  if (stat.isSocket()) {
    // We do something with the socket
  }

}

Upvotes: 2

Related Questions