diff --git a/lib/fs.js b/lib/fs.js index 49b4d434e81..99d63476907 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1839,7 +1839,12 @@ fs.mkdtempSync = function(prefix, options) { prefix); } nullCheck(prefix, 'prefix'); - return binding.mkdtemp(`${prefix}XXXXXX`, options.encoding); + const path = `${prefix}XXXXXX`; + const ctx = { path }; + const result = binding.mkdtemp(path, options.encoding, + undefined, ctx); + handleErrorFromBinding(ctx); + return result; }; diff --git a/src/node_file.cc b/src/node_file.cc index 3152d2067c1..d73b5450dab 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -1608,7 +1608,8 @@ static void FUTimes(const FunctionCallbackInfo& args) { static void Mkdtemp(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - CHECK_GE(args.Length(), 2); + const int argc = args.Length(); + CHECK_GE(argc, 2); BufferValue tmpl(env->isolate(), args[0]); CHECK_NE(*tmpl, nullptr); @@ -1616,18 +1617,22 @@ static void Mkdtemp(const FunctionCallbackInfo& args) { const enum encoding encoding = ParseEncoding(env->isolate(), args[1], UTF8); FSReqBase* req_wrap = GetReqWrap(env, args[2]); - if (req_wrap != nullptr) { + if (req_wrap != nullptr) { // mkdtemp(tmpl, encoding, req) AsyncCall(env, req_wrap, args, "mkdtemp", encoding, AfterStringPath, uv_fs_mkdtemp, *tmpl); - } else { - SYNC_CALL(mkdtemp, *tmpl, *tmpl); - const char* path = static_cast(SYNC_REQ.path); + } else { // mkdtemp(tmpl, encoding, undefined, ctx) + CHECK_EQ(argc, 4); + fs_req_wrap req_wrap; + SyncCall(env, args[3], &req_wrap, "mkdtemp", + uv_fs_mkdtemp, *tmpl); + const char* path = static_cast(req_wrap.req.path); Local error; MaybeLocal rc = StringBytes::Encode(env->isolate(), path, encoding, &error); if (rc.IsEmpty()) { - env->isolate()->ThrowException(error); + Local ctx = args[3].As(); + ctx->Set(env->context(), env->error_string(), error).FromJust(); return; } args.GetReturnValue().Set(rc.ToLocalChecked()); diff --git a/test/parallel/test-fs-error-messages.js b/test/parallel/test-fs-error-messages.js index 5ded7d23405..29056e8b669 100644 --- a/test/parallel/test-fs-error-messages.js +++ b/test/parallel/test-fs-error-messages.js @@ -25,6 +25,7 @@ const fixtures = require('../common/fixtures'); const assert = require('assert'); const fs = require('fs'); const nonexistentFile = fixtures.path('non-existent'); +const nonexistentDir = fixtures.path('non-existent', 'foo', 'bar'); const existingFile = fixtures.path('exit.js'); const existingFile2 = fixtures.path('create-file.js'); const existingDir = fixtures.path('empty'); @@ -607,3 +608,29 @@ if (!common.isAIX) { validateError ); } + +// mkdtemp +{ + const validateError = (err) => { + const pathPrefix = new RegExp('^' + re`${nonexistentDir}`); + assert(pathPrefix.test(err.path), + `Expect ${err.path} to match ${pathPrefix}`); + + const prefix = new RegExp('^ENOENT: no such file or directory, mkdtemp ' + + re`'${nonexistentDir}`); + assert(prefix.test(err.message), + `Expect ${err.message} to match ${prefix}`); + + assert.strictEqual(err.errno, uv.UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'mkdtemp'); + return true; + }; + + fs.mkdtemp(nonexistentDir, common.mustCall(validateError)); + + assert.throws( + () => fs.mkdtempSync(nonexistentDir), + validateError + ); +}