I googled
EPERM: operation not permitted
and I got many hits on issues with npm and this error.
This is not my case ( not a duplicate ) as I am not running npm, I am running my own Node code.
I am getting this error:
Error
{
Error: 'EPERM: operation not permitted',
errno: -1,
code: 'EPERM',
syscall: 'scandir',
path: '../../../Library/Application Support/CallHistoryDB/'
};
when running the code below on my home directory.
I ran it using both
node getInfo
and
sudo node getInfo
but I get the same error.
This code works fine if I run it on my local repository but when I try to traverse my entire home directory I get the error.
Executed code:
// Libraries
const fs = require('fs');
const h = require('./helper');
// Start recursing here
const start = '../../../';
// API
getThings(start).then(() => {
console.log(data);
}).catch(h.error)
// Accesses the file system and returns an array of files / folders
async function getThings (folder) {
const things = await fs.promises.readdir(folder);
for(let i = 0; i < things.length; i++) {
await getStats(things[i], folder);
}
}
// Gets statistics for each file/folder
async function getStats (thing, folder) {
const path = folder + thing;
const stats = await fs.promises.stat(path);
await checkForFolder(stats, thing, path);
}
// if the file/folder is a folder, recurse and do it again
async function checkForFolder(stats, thing, path){
// logThing(stats, thing, path);
if (stats.isDirectory() ) {
await getThings(path + '/');
}
}
Research
'../../../Library/Application Support/CallHistoryDB/'
This path is protected by macOS security settings, as it may contain sensitive telephone history data.
If you specifically need to access it in your Node application, you will need to enable full disk access for the application you're using to run this script (e.g, Terminal.app, iTerm, or an IDE) in System Preferences, as shown below. Note that this will give all applications you run in the terminal access to your sensitive personal files; tread carefully.
However, if you don't need to specifically access this path (and you probably shouldn't), a better solution may be to catch errors individually on each call to fs.promises.stat(path)
. The simplest way of doing this will be to wrap the call to await fs.promises.stat(path)
in a try … catch
block and either print or ignore errors.