nodejs/node

missing error.path at fs.mkdir callback on last call

thisconnect opened this issue · 10 comments

Expected to always have an Error with errno, code, syscall and path.

In the following 2 examples one error contains path and the other one doesn't.

  • Version: v12.3.1
  • Platform: Darwin computer.local 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64
  • Subsystem: fs
const fs = require('fs');
fs.writeFileSync('./test2.txt', '');

// missing error.path
fs.mkdir('./test2.txt/sub/dir/dir/dir', {
  recursive: true
}, function(err) {
  console.log('\n\nerr', err)
  console.log('with recursive:true error is MISSING err.path', err.path)
});

// error.path ok
fs.mkdir('./test2.txt/sub/dir/dir/dir', {
  recursive: false
}, function(err) {
  console.log('\n\nerr', err)
  console.log('with recursive:false err.path is', err.path)
});

I believe this was working with older node 10.x versions, possibly related to a change in #27198

Output:

err [Error: ENOTDIR: not a directory, mkdir './test2.txt/sub/dir/dir/dir'] {
  errno: -20,
  code: 'ENOTDIR',
  syscall: 'mkdir',
  path: './test2.txt/sub/dir/dir/dir'
}
with recursive:false err.path is ./test2.txt/sub/dir/dir/dir


err [Error: ENOTDIR: not a directory, mkdir] {
  errno: -20,
  code: 'ENOTDIR',
  syscall: 'mkdir'
}
with recursive:true error is MISSING err.path undefined
Trott commented

/ping @bcoe

fs.writeFileSync('./test2.txt', ''); is the culprit

const fs = require('fs')
fs.writeFileSync('./text', '')
fs.mkdirSync('./text')

v12.3.0

>node index2.js
internal/fs/utils.js:461
    throw err;
    ^

Error: EEXIST: file already exists, mkdir './text'
?[90m    at Object.mkdirSync (fs.js:748:3)?[39m
    at Object.<anonymous> (C:\Users\himself65\Desktop\Github\test\index2.js:3:4)
?[90m    at Module._compile (internal/modules/cjs/loader.js:774:30)?[39m
?[90m    at Object.Module._extensions..js (internal/modules/cjs/loader.js:785:10)?[39m
?[90m    at Module.load (internal/modules/cjs/loader.js:641:32)?[39m
?[90m    at Function.Module._load (internal/modules/cjs/loader.js:556:12)?[39m
?[90m    at Function.Module.runMain (internal/modules/cjs/loader.js:837:10)?[39m
?[90m    at internal/main/run_main_module.js:17:11?[39m {
  errno: ?[33m-4075?[39m,
  syscall: ?[32m'mkdir'?[39m,
  code: ?[32m'EEXIST'?[39m,
  path: ?[32m'./text'?[39m
}

In the Unix platform, we cannot create the file and folder which are the same name, because everything is a file in Unix.

what's more, if we really create it, what's the happened in this example?

const fs = require('fs')
fs.writeFileSync('./text', '')
fs.mkdirSync('./text')

// what will happened here???
fs.statSync('./text')

In the Windows platform, I think it's the same reason

AfterNoArgs, mkdirp ? MKDirpAsync : uv_fs_mkdir, *path, mode);

and when make dir loop call MKDirpAsync

const fs = require('fs')
fs.writeFileSync('./foo', '')
try {
  fs.mkdirSync('./foo/foo/foo', { recursive: true })
} catch (e) {
  console.log(e)
  console.log(e.path)
}
console.log('\n\n\n')
fs.mkdir('./foo/foo/foo', { recursive: true }, (e) => {
  console.log(e)
  console.log(e.path)
})
>node index2.js
Error: ENOTDIR: not a directory, mkdir './foo/foo/foo'
    at Object.mkdirSync (fs.js:748:3)
    at Object.<anonymous> (C:\Users\himself65\Desktop\Github\test\index2.js:4:6)
    at Module._compile (internal/modules/cjs/loader.js:774:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:785:10)
    at Module.load (internal/modules/cjs/loader.js:641:32)
    at Function.Module._load (internal/modules/cjs/loader.js:556:12)
    at Function.Module.runMain (internal/modules/cjs/loader.js:837:10)
    at internal/main/run_main_module.js:17:11 {
  errno: -4052,
  syscall: 'mkdir',
  code: 'ENOTDIR',
  path: './foo/foo/foo'
}
./foo/foo/foo




[Error: ENOTDIR: not a directory, mkdir] {
  errno: -4052,
  code: 'ENOTDIR',
  syscall: 'mkdir'
}
undefined

In the Unix platform, we cannot create the file and folder which are the same name, because everything is a file in Unix.

correct, but the issue is only about that path is missing in this error. I update the description. Sorry I should have written a better description.

i get it. and I believe something escaped this line

AfterNoArgs, mkdirp ? MKDirpAsync : uv_fs_mkdir, *path, mode);

const assert = require('assert')
const fs = require('fs')
const path = require('path')
const file = path.join(__dirname, 'foo')
const dir = path.join(file, './foo/foo')

fs.writeFileSync(file, '')
fs.mkdir(dir, { recursive: true }, function (err) {
  console.log(err)
})

fs.mkdir(dir, { recursive: false }, function (err) {
  console.log(err)
})
fs.mkdir(dir, { recursive: false }, function (err) {
  console.log(err)
})
fs.mkdir(dir, { recursive: false }, function (err) {
  console.log(err)
})
fs.mkdir(dir, { recursive: false }, function (err) {
  console.log(err)
})
C:\Users\himself65\Desktop\Github\test>node index2.js
[Error: ENOENT: no such file or directory, mkdir 'C:\Users\himself65\Desktop\Github\test\foo\foo\foo'] {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'mkdir',
  path: 'C:\\Users\\himself65\\Desktop\\Github\\test\\foo\\foo\\foo'
}
[Error: ENOENT: no such file or directory, mkdir 'C:\Users\himself65\Desktop\Github\test\foo\foo\foo'] {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'mkdir',
  path: 'C:\\Users\\himself65\\Desktop\\Github\\test\\foo\\foo\\foo'
}
[Error: ENOENT: no such file or directory, mkdir 'C:\Users\himself65\Desktop\Github\test\foo\foo\foo'] {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'mkdir',
  path: 'C:\\Users\\himself65\\Desktop\\Github\\test\\foo\\foo\\foo'
}
[Error: ENOENT: no such file or directory, mkdir 'C:\Users\himself65\Desktop\Github\test\foo\foo\foo'] {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'mkdir',
  path: 'C:\\Users\\himself65\\Desktop\\Github\\test\\foo\\foo\\foo'
}
[Error: ENOTDIR: not a directory, mkdir] {
  errno: -4052,
  code: 'ENOTDIR',
  syscall: 'mkdir'
}

I think the actual bug is a missing path on last call

so, this issue title should change to missing error.path at fs.mkdir callback on last call