fs: calling mkdir in fs.cp function can ignore EEXIST error
This PR mainly aims to solve the following problem. During the execution of the fsp.cp function, due to other file operations, the target directory of fsp.cp is created in parallel. The actual situation may be more complicated. Multiple file operations are executed concurrently, resulting in an error in the internal fsp.cp when calling mkdir, because the folder has been created by other file operations. In this case, you can actually ignore this error and continue with the subsequent file copying operation.
import { promises as fsp } from 'fs'
const src = 'T:/src/'
const dst = 'T:/out/'
try {
await fsp.rm(dst, { recursive: true })
} catch { }
await Promise.all([
fsp.cp(src, dst, {
recursive: true,
force: true,
errorOnExist: false,
mode: 0
}),
// example other file operations in parallel
fsp.mkdir(dst, { recursive: true })
])
// throws EEXIST: file already exists, mkdir 'T:/out/'
// at mkdir()
// at mkDirAndCopy() lib/internal/fs/cp/cp.js
// at onDir() lib/internal/fs/cp/cp.js
The relevant code is in lib/internal/fs/cp/cp.js. destStat is empty here, it did not exist when checking the folder before.
function onDir(srcStat, destStat, src, dest, opts) {
if (!destStat) return mkDirAndCopy(srcStat.mode, src, dest, opts);
return copyDir(src, dest, opts);
}
async function mkDirAndCopy(srcMode, src, dest, opts) {
await mkdir(dest);
await copyDir(src, dest, opts);
return setDestMode(dest, srcMode);
}
I want to ignore the EEXIST error thrown by mkdir
async function mkDirAndCopy(srcMode, src, dest, opts) {
try {
await mkdir(dest);
} catch (error) {
// If the folder already exists, skip it.
if (error.code !== 'EEXIST')
throw error;
}
await copyDir(src, dest, opts);
return setDestMode(dest, srcMode);
}