Skip to content

Commit d2c4f50

Browse files
committed
fs: throw readdirSync errors in JS
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 72d150e commit d2c4f50

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

lib/fs.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,11 @@ fs.readdirSync = function(path, options) {
819819
options = getOptions(options, {});
820820
path = getPathFromURL(path);
821821
validatePath(path);
822-
return binding.readdir(pathModule.toNamespacedPath(path), options.encoding);
822+
const ctx = { path };
823+
const result = binding.readdir(pathModule.toNamespacedPath(path),
824+
options.encoding, undefined, ctx);
825+
handleErrorFromBinding(ctx);
826+
return result;
823827
};
824828

825829
fs.fstat = function(fd, callback) {

src/node_file.cc

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,21 +1090,28 @@ static void RealPath(const FunctionCallbackInfo<Value>& args) {
10901090
static void ReadDir(const FunctionCallbackInfo<Value>& args) {
10911091
Environment* env = Environment::GetCurrent(args);
10921092

1093-
CHECK_GE(args.Length(), 1);
1093+
const int argc = args.Length();
1094+
CHECK_GE(argc, 3);
10941095

10951096
BufferValue path(env->isolate(), args[0]);
10961097
CHECK_NE(*path, nullptr);
10971098

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

11001101
FSReqBase* req_wrap = GetReqWrap(env, args[2]);
1101-
if (req_wrap != nullptr) {
1102+
if (req_wrap != nullptr) { // readdir(path, encoding, req)
11021103
AsyncCall(env, req_wrap, args, "scandir", encoding, AfterScanDir,
11031104
uv_fs_scandir, *path, 0 /*flags*/);
1104-
} else {
1105-
SYNC_CALL(scandir, *path, *path, 0 /*flags*/)
1105+
} else { // readdir(path, encoding, undefined, ctx)
1106+
CHECK_EQ(argc, 4);
1107+
fs_req_wrap req_wrap;
1108+
int err = SyncCall(env, args[3], &req_wrap, "scandir",
1109+
uv_fs_scandir, *path, 0 /*flags*/);
1110+
if (err < 0) {
1111+
return; // syscall failed, no need to continue, error info is in ctx
1112+
}
11061113

1107-
CHECK_GE(SYNC_REQ.result, 0);
1114+
CHECK_GE(req_wrap.req.result, 0);
11081115
int r;
11091116
Local<Array> names = Array::New(env->isolate(), 0);
11101117
Local<Function> fn = env->push_values_to_array_function();
@@ -1114,19 +1121,26 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
11141121
for (int i = 0; ; i++) {
11151122
uv_dirent_t ent;
11161123

1117-
r = uv_fs_scandir_next(&SYNC_REQ, &ent);
1124+
r = uv_fs_scandir_next(&(req_wrap.req), &ent);
11181125
if (r == UV_EOF)
11191126
break;
1120-
if (r != 0)
1121-
return env->ThrowUVException(r, "readdir", "", *path);
1127+
if (r != 0) {
1128+
Local<Object> ctx = args[3].As<Object>();
1129+
ctx->Set(env->context(), env->errno_string(),
1130+
Integer::New(env->isolate(), r)).FromJust();
1131+
ctx->Set(env->context(), env->syscall_string(),
1132+
OneByteString(env->isolate(), "readdir")).FromJust();
1133+
return;
1134+
}
11221135

11231136
Local<Value> error;
11241137
MaybeLocal<Value> filename = StringBytes::Encode(env->isolate(),
11251138
ent.name,
11261139
encoding,
11271140
&error);
11281141
if (filename.IsEmpty()) {
1129-
env->isolate()->ThrowException(error);
1142+
Local<Object> ctx = args[3].As<Object>();
1143+
ctx->Set(env->context(), env->error_string(), error).FromJust();
11301144
return;
11311145
}
11321146

0 commit comments

Comments
 (0)