Skip to content

Commit 72d150e

Browse files
committed
fs: throw realpathSync.native errors in JS
PR-URL: #18871 Refs: #18106 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
1 parent 77b42e3 commit 72d150e

File tree

3 files changed

+43
-7
lines changed

3 files changed

+43
-7
lines changed

lib/fs.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1649,7 +1649,10 @@ fs.realpathSync.native = function(path, options) {
16491649
options = getOptions(options, {});
16501650
path = getPathFromURL(path);
16511651
validatePath(path);
1652-
return binding.realpath(path, options.encoding);
1652+
const ctx = { path };
1653+
const result = binding.realpath(path, options.encoding, undefined, ctx);
1654+
handleErrorFromBinding(ctx);
1655+
return result;
16531656
};
16541657

16551658

src/node_file.cc

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,30 +1047,42 @@ static void MKDir(const FunctionCallbackInfo<Value>& args) {
10471047
}
10481048

10491049
static void RealPath(const FunctionCallbackInfo<Value>& args) {
1050-
CHECK_GE(args.Length(), 2);
10511050
Environment* env = Environment::GetCurrent(args);
1051+
1052+
const int argc = args.Length();
1053+
CHECK_GE(argc, 3);
1054+
10521055
BufferValue path(env->isolate(), args[0]);
10531056
CHECK_NE(*path, nullptr);
10541057

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

10571060
FSReqBase* req_wrap = GetReqWrap(env, args[2]);
1058-
if (req_wrap != nullptr) {
1061+
if (req_wrap != nullptr) { // realpath(path, encoding, req)
10591062
AsyncCall(env, req_wrap, args, "realpath", encoding, AfterStringPtr,
10601063
uv_fs_realpath, *path);
1061-
} else {
1062-
SYNC_CALL(realpath, *path, *path);
1063-
const char* link_path = static_cast<const char*>(SYNC_REQ.ptr);
1064+
} else { // realpath(path, encoding, undefined, ctx)
1065+
CHECK_EQ(argc, 4);
1066+
fs_req_wrap req_wrap;
1067+
int err = SyncCall(env, args[3], &req_wrap, "realpath",
1068+
uv_fs_realpath, *path);
1069+
if (err < 0) {
1070+
return; // syscall failed, no need to continue, error info is in ctx
1071+
}
1072+
1073+
const char* link_path = static_cast<const char*>(req_wrap.req.ptr);
10641074

10651075
Local<Value> error;
10661076
MaybeLocal<Value> rc = StringBytes::Encode(env->isolate(),
10671077
link_path,
10681078
encoding,
10691079
&error);
10701080
if (rc.IsEmpty()) {
1071-
env->isolate()->ThrowException(error);
1081+
Local<Object> ctx = args[3].As<Object>();
1082+
ctx->Set(env->context(), env->error_string(), error).FromJust();
10721083
return;
10731084
}
1085+
10741086
args.GetReturnValue().Set(rc.ToLocalChecked());
10751087
}
10761088
}

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,27 @@ function re(literals, ...values) {
125125
);
126126
}
127127

128+
// native realpath
129+
{
130+
const validateError = (err) => {
131+
assert.strictEqual(nonexistentFile, err.path);
132+
assert.strictEqual(
133+
err.message,
134+
`ENOENT: no such file or directory, realpath '${nonexistentFile}'`);
135+
assert.strictEqual(err.errno, uv.UV_ENOENT);
136+
assert.strictEqual(err.code, 'ENOENT');
137+
assert.strictEqual(err.syscall, 'realpath');
138+
return true;
139+
};
140+
141+
fs.realpath.native(nonexistentFile, common.mustCall(validateError));
142+
143+
assert.throws(
144+
() => fs.realpathSync.native(nonexistentFile),
145+
validateError
146+
);
147+
}
148+
128149
// readlink
129150
{
130151
const validateError = (err) => {

0 commit comments

Comments
 (0)