Skip to content

Commit d2dc2a5

Browse files
committed
fs: throw fs.mkdtempSync errors in JS land
PR-URL: #18871 Refs: #18106 Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent 82523d3 commit d2dc2a5

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed

lib/fs.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1839,7 +1839,12 @@ fs.mkdtempSync = function(prefix, options) {
18391839
prefix);
18401840
}
18411841
nullCheck(prefix, 'prefix');
1842-
return binding.mkdtemp(`${prefix}XXXXXX`, options.encoding);
1842+
const path = `${prefix}XXXXXX`;
1843+
const ctx = { path };
1844+
const result = binding.mkdtemp(path, options.encoding,
1845+
undefined, ctx);
1846+
handleErrorFromBinding(ctx);
1847+
return result;
18431848
};
18441849

18451850

src/node_file.cc

+11-6
Original file line numberDiff line numberDiff line change
@@ -1608,26 +1608,31 @@ static void FUTimes(const FunctionCallbackInfo<Value>& args) {
16081608
static void Mkdtemp(const FunctionCallbackInfo<Value>& args) {
16091609
Environment* env = Environment::GetCurrent(args);
16101610

1611-
CHECK_GE(args.Length(), 2);
1611+
const int argc = args.Length();
1612+
CHECK_GE(argc, 2);
16121613

16131614
BufferValue tmpl(env->isolate(), args[0]);
16141615
CHECK_NE(*tmpl, nullptr);
16151616

16161617
const enum encoding encoding = ParseEncoding(env->isolate(), args[1], UTF8);
16171618

16181619
FSReqBase* req_wrap = GetReqWrap(env, args[2]);
1619-
if (req_wrap != nullptr) {
1620+
if (req_wrap != nullptr) { // mkdtemp(tmpl, encoding, req)
16201621
AsyncCall(env, req_wrap, args, "mkdtemp", encoding, AfterStringPath,
16211622
uv_fs_mkdtemp, *tmpl);
1622-
} else {
1623-
SYNC_CALL(mkdtemp, *tmpl, *tmpl);
1624-
const char* path = static_cast<const char*>(SYNC_REQ.path);
1623+
} else { // mkdtemp(tmpl, encoding, undefined, ctx)
1624+
CHECK_EQ(argc, 4);
1625+
fs_req_wrap req_wrap;
1626+
SyncCall(env, args[3], &req_wrap, "mkdtemp",
1627+
uv_fs_mkdtemp, *tmpl);
1628+
const char* path = static_cast<const char*>(req_wrap.req.path);
16251629

16261630
Local<Value> error;
16271631
MaybeLocal<Value> rc =
16281632
StringBytes::Encode(env->isolate(), path, encoding, &error);
16291633
if (rc.IsEmpty()) {
1630-
env->isolate()->ThrowException(error);
1634+
Local<Object> ctx = args[3].As<Object>();
1635+
ctx->Set(env->context(), env->error_string(), error).FromJust();
16311636
return;
16321637
}
16331638
args.GetReturnValue().Set(rc.ToLocalChecked());

test/parallel/test-fs-error-messages.js

+27
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const fixtures = require('../common/fixtures');
2525
const assert = require('assert');
2626
const fs = require('fs');
2727
const nonexistentFile = fixtures.path('non-existent');
28+
const nonexistentDir = fixtures.path('non-existent', 'foo', 'bar');
2829
const existingFile = fixtures.path('exit.js');
2930
const existingFile2 = fixtures.path('create-file.js');
3031
const existingDir = fixtures.path('empty');
@@ -607,3 +608,29 @@ if (!common.isAIX) {
607608
validateError
608609
);
609610
}
611+
612+
// mkdtemp
613+
{
614+
const validateError = (err) => {
615+
const pathPrefix = new RegExp('^' + re`${nonexistentDir}`);
616+
assert(pathPrefix.test(err.path),
617+
`Expect ${err.path} to match ${pathPrefix}`);
618+
619+
const prefix = new RegExp('^ENOENT: no such file or directory, mkdtemp ' +
620+
re`'${nonexistentDir}`);
621+
assert(prefix.test(err.message),
622+
`Expect ${err.message} to match ${prefix}`);
623+
624+
assert.strictEqual(err.errno, uv.UV_ENOENT);
625+
assert.strictEqual(err.code, 'ENOENT');
626+
assert.strictEqual(err.syscall, 'mkdtemp');
627+
return true;
628+
};
629+
630+
fs.mkdtemp(nonexistentDir, common.mustCall(validateError));
631+
632+
assert.throws(
633+
() => fs.mkdtempSync(nonexistentDir),
634+
validateError
635+
);
636+
}

0 commit comments

Comments
 (0)