3

My first time ever trying to traverse directories, but stat is throwing errors for some of the directories due to what seems to be a lack of permission.

Error: EPERM: operation not permitted, stat 'K:\System Volume Information'

I'd like to simply avoid calling stat on a given directory in the first place if it is going to throw an error, yet I can't figure out how to do it.

I've tried looking into ignoring protected directories altogether. However, all of the questions I came across used regular expressions that – to my limited knowledge of MacOS, Linux, and how things are handled under the hood on Windows – didn't seem to be applicable to the Windows environment.

I've tried checking the read and write permissions of the directory before making any call to stat, but this doesn't seem to do anything?

async function scanDirs(){
  const
    r = await fsp.readFile('./config.json', 'utf8'),
    archives = JSON.parse(r).archives,
    fs = require('fs'),
    { join } = require('path'),
    traverse = async (dir) => {
      try {
        const perm = await fsp.access(dir, fs.constants.R_OK)
        if (perm === undefined){
          const stats = await fsp.stat(dir)
          if (stats.isDirectory()){
            const subfolders = await fsp.readdir(dir)
            subfolders.forEach(path => {
              const fullPath = join(dir, path)
              traverse( fullPath )
            })
          }
        }
      }
      catch (error){
        console.error(error)
      }
    }

  for (const dir of archives){
    traverse(dir)
  }
}

I've also just tried checking the permissions of a given folder's children before feeding them back into traverse, but this doesn't work either.

            for (const path of subfolders){
              const
                fullPath = join(dir, path),
                perm = await fsp.access(fullPath, fs.constants.R_OK)
              if (perm === undefined) traverse(fullPath)
            }

Any help would be appreciated.

oldboy
  • 5,729
  • 6
  • 38
  • 86
  • 1
    It can often be subject to race conditions to try to check things before doing an asynchronous operation (this is why `fs.exists()` is deprecated, for example). Usually, it's better to just attempt the operation and properly handle any errors you get. Is there a reason you're afraid to just attempt the operation and properly handle errors? Plus, you can't pre-test all possible errors anyway so you have to handle errors on the major operation anyway. – jfriend00 Oct 30 '19 at 07:29
  • 1
    Handling errors then just becomes a task to decide which errors should be skipped and continue other processing and which errors are fatal and the operation should be aborted. – jfriend00 Oct 30 '19 at 07:44
  • @jfriend00 i dont believe the code introduces any race situations since `await` is being used? the one error id like to avoid altogether is merely the permissions error. theres two ways to go about it: (1) check the permissions before doing anything else, which doesnt seem to be working for some reason; or (2) somehow acknowledge to avoid querying hidden drives and files which im not even sure can be done. i know `exists` is deprecated, but the documentation suggests using `access` and `stat` which is what im doing? – oldboy Oct 30 '19 at 21:41
  • @jfriend00 i mean i could just ignore the caught errors, but if i can just avoid code that throws those errors in the first place, so that they dont distract my attention from other possible errors, that would be ideal – oldboy Oct 30 '19 at 22:07
  • 1
    @PrimitiveNom The race condition exists because other programs might change the permissions while your application is traversing the directory. It might happen that the permissions change between the `access` call and the `stat` call. – Bergi Oct 30 '19 at 23:34
  • @Bergi ahhh right right damn. nonetheless, i dont think the permissions of system files/folders will be changing that regularly – oldboy Oct 30 '19 at 23:38
  • Of course you can decide to not care about errors that crash your program because they are too rare, but in this case I can't see a reason not to use the proper solution that is both simpler and more robust. – Bergi Oct 30 '19 at 23:44
  • @Bergi which is? – oldboy Oct 31 '19 at 07:38
  • @PrimitiveNom Which is handling errors as jfriend suggested – Bergi Oct 31 '19 at 09:31
  • @Bergi the errors will be handled nonetheless, but id rather not call `stat` or some other method that is going to throw an error due to a lack of permissions if i can simply check permissions before calling the method that throws the error due to a lack of permission – oldboy Oct 31 '19 at 09:47

0 Answers0