diff --git a/src/node_file.cc b/src/node_file.cc index fbab726afb4fa0..c3ab573b2995d4 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -1246,6 +1246,9 @@ int MKDirpSync(uv_loop_t* loop, case UV_EPERM: { return err; } + case UV_EACCES: { + return err; + } default: uv_fs_req_cleanup(req); int orig_err = err; @@ -1322,6 +1325,10 @@ int MKDirpAsync(uv_loop_t* loop, req_wrap->continuation_data()->Done(err); break; } + case UV_EACCES: { + req_wrap->continuation_data()->Done(err); + break; + } default: uv_fs_req_cleanup(req); // Stash err for use in the callback. diff --git a/test/parallel/test-fs-mkdir-recursive-eaccess.js b/test/parallel/test-fs-mkdir-recursive-eaccess.js new file mode 100644 index 00000000000000..cb420c18489748 --- /dev/null +++ b/test/parallel/test-fs-mkdir-recursive-eaccess.js @@ -0,0 +1,50 @@ +'use strict'; + +// Test that mkdir with recursive option returns appropriate error +// when executed on folder it does not have permission to access. +// Ref: https://github.com/nodejs/node/issues/31481 + +const common = require('../common'); + +if (!common.isWindows && process.getuid() === 0) + common.skip('as this test should not be run as `root`'); + +if (common.isIBMi) + common.skip('IBMi has a different access permission mechanism'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +let n = 0; + +// Synchronous API should return an EACCESS error with path populated. +{ + const dir = path.join(tmpdir.path, `mkdirp_${n++}`); + fs.mkdirSync(dir); + fs.chmodSync(dir, '444'); + let err = null; + try { + fs.mkdirSync(path.join(dir, '/foo'), { recursive: true }); + } catch (_err) { + err = _err; + } + assert(err); + assert.strictEqual(err.code, 'EACCES'); + assert(err.path); +} + +// Asynchronous API should return an EACCESS error with path populated. +{ + const dir = path.join(tmpdir.path, `mkdirp_${n++}`); + fs.mkdirSync(dir); + fs.chmodSync(dir, '444'); + fs.mkdir(path.join(dir, '/bar'), { recursive: true }, (err) => { + assert(err); + assert.strictEqual(err.code, 'EACCES'); + assert(err.path); + }); +}