fs: throw fs.mkdtempSync errors in JS land

PR-URL: https://github.com/nodejs/node/pull/18871
Refs: https://github.com/nodejs/node/issues/18106
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
This commit is contained in:
Joyee Cheung 2018-02-20 04:54:19 +08:00
parent 82523d3b6e
commit d2dc2a5011
No known key found for this signature in database
GPG Key ID: F586868AAD831D0C
3 changed files with 44 additions and 7 deletions

View File

@ -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;
};

View File

@ -1608,7 +1608,8 @@ 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);
@ -1616,18 +1617,22 @@ static void Mkdtemp(const FunctionCallbackInfo<Value>& 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<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());

View File

@ -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
);
}