Skip to content

Commit

Permalink
fs: throw fs.mkdtempSync errors in JS land
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
joyeecheung committed Feb 27, 2018
1 parent 82523d3 commit d2dc2a5
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 7 deletions.
7 changes: 6 additions & 1 deletion lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};


Expand Down
17 changes: 11 additions & 6 deletions src/node_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1608,26 +1608,31 @@ static void FUTimes(const FunctionCallbackInfo<Value>& args) {
static void Mkdtemp(const FunctionCallbackInfo<Value>& 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);

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<const char*>(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<const char*>(req_wrap.req.path);

Local<Value> error;
MaybeLocal<Value> rc =
StringBytes::Encode(env->isolate(), path, encoding, &error);
if (rc.IsEmpty()) {
env->isolate()->ThrowException(error);
Local<Object> ctx = args[3].As<Object>();
ctx->Set(env->context(), env->error_string(), error).FromJust();
return;
}
args.GetReturnValue().Set(rc.ToLocalChecked());
Expand Down
27 changes: 27 additions & 0 deletions test/parallel/test-fs-error-messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -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
);
}

0 comments on commit d2dc2a5

Please sign in to comment.