I am trying to write a number of files in node to a specific folder, but I am having some issues when creating the folder:
I got an upload.js file that recieves two files from the front end, then I am using an async for loop not to block the event loop, and I have a function that I run for each file it receives, this funtion checks if the folder exists and if not it creates it:
import Router from 'express'
import multer from 'multer'
import { resolve } from 'path'
import { constants } from 'fs'
import { writeFile, mkdir, access } from 'fs/promises'
async function asyncForEach(array, callback) {
for (let i = 0, j = array.length; i < j; i++) {
await callback(array[i], i, array)
}
}
router.put('/', upload.array('files', 5), async (req, res) => {
const { files } = req
const temporalFolder = `./tmp`
const writeToFolder = async (name, file) => {
try {
await access(temporalFolder, constants.R_OK | constants.W_OK)
} catch (error) {
await mkdir(temporalFolder)
} finally {
await writeFile(resolve(temporalFolder, name), file)
}
}
await asyncForEach(files, async (file) => {
const { originalname, buffer } = file
writeToFolder(originalname, buffer)
}
res.end()
})
export default router
If the folder is already created I get no error and it works fine, but the first time when the folder does not exist I get this even thou all works:
[Error: EEXIST: file already exists, mkdir './tmp'] {
errno: -17,
code: 'EEXIST',
syscall: 'mkdir',
path: './tmp'
}
Update: Thanks to Rajdeep Debnath I fixed it with this:
const writeToFolder = async (name, file) => {
try {
await access(temporalFolder, constants.R_OK | constants.W_OK)
} catch (error) {
await mkdir(temporalFolder, { recursive: true })
} finally {
await writeFile(resolve(temporalFolder, name), file)
}
}
writeToFolderto be executed before theasyncForEach. There's no need to check the existance of the folder again for every file to be written...await access(...)and one of them throws an error? Because if that's the case, it will go into thecatchblock and try to create the directory, even ifaccessdidn't throw an error ... Just add aconsole.log(error)right beforeawait mkdir(...)to see, what error was thrown, to cause thecatchto be executedaccess, could it be related to theRace Conditionreferred in that Func's documentation? "Using fsPromises.access() to check for the accessibility of a file before calling fsPromises.open() is not recommended. Doing so introduces a race condition, since other processes may change the file's state between the two calls. Instead, user code should open/read/write the file directly and handle the error raised if the file is not accessible." ref: nodejs.org/api/fs.html#fs_fspromises_access_path_mode