Node.js报错ENOTDIR:scandir非目录问题的排查与修复方案
Discord机器人ENOTDIR错误原因及修复方案
问题详情
开发Discord机器人Logs功能时出现异常,移除bot.js中相关代码后仍报错,错误信息如下:
node:internal/fs/utils:351 throw err; ^ Error: ENOTDIR: not a directory, scandir './src/functions/.DS_Store' at Object.readdirSync (node:fs:1532:3) at Object.<anonymous> (/Users/roopa/Desktop/projects/LLbot/src/bot.js:43:6) at Module._compile (node:internal/modules/cjs/loader:1255:14) at Module._extensions..js (node:internal/modules/cjs/loader:1309:10) at Module.load (node:internal/modules/cjs/loader:1113:32) at Module._load (node:internal/modules/cjs/loader:960:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12) at node:internal/main/run_main_module:23:47 { errno: -20, syscall: 'scandir', code: 'ENOTDIR', path: './src/functions/.DS_Store' }
引发错误的代码片段:
const functionFolders = fs.readdirSync(`./src/functions`); for (const folder of functionFolders) { const functionFiles = fs .readdirSync(`./src/functions/${folder}`) .filter((file) => file.endsWith(".js")); for (const file of functionFiles) require(`./functions/${folder}/${file}`); }
错误原因
ENOTDIR错误意味着代码试图对非目录文件执行目录操作,具体原因:
fs.readdirSync('./src/functions')会读取该目录下所有内容,包括Mac系统自动生成的隐藏文件.DS_Store(这是文件,不是目录)- 循环中直接把每个读取到的项当作目录处理,调用
fs.readdirSync('./src/functions/.DS_Store')时,因目标是文件而非目录,触发报错。
修复方案
方案1:通用过滤(推荐)
在处理前判断每个项是否为目录,只对目录执行后续操作:
const fs = require('fs'); const path = require('path'); const functionsDir = './src/functions'; const functionFolders = fs.readdirSync(functionsDir); for (const folder of functionFolders) { const folderPath = path.join(functionsDir, folder); // 跳过非目录项 if (!fs.statSync(folderPath).isDirectory()) continue; const functionFiles = fs .readdirSync(folderPath) .filter((file) => file.endsWith(".js")); for (const file of functionFiles) require(`./functions/${folder}/${file}`); }
方案2:针对性过滤.DS_Store
如果仅需解决Mac系统的这个特定文件问题,可直接在读取结果中过滤掉.DS_Store:
const functionFolders = fs.readdirSync(`./src/functions`).filter(item => item !== '.DS_Store'); for (const folder of functionFolders) { const functionFiles = fs .readdirSync(`./src/functions/${folder}`) .filter((file) => file.endsWith(".js")); for (const file of functionFiles) require(`./functions/${folder}/${file}`); }
额外建议
- 将
.DS_Store添加到项目的.gitignore文件中,避免提交到版本库 - 方案1能适配所有非目录干扰项,通用性更强,优先选择
内容的提问来源于stack exchange,提问作者Joe Mama
相关产品推荐
相关产品推荐

