Skip to content

Commit 90cd780

Browse files
jasnelladuh95
authored andcommitted
src: make more error handling improvements
PR-URL: #57262 Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent 3bf546c commit 90cd780

8 files changed

+131
-85
lines changed

src/env.cc

+49-35
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ using v8::HeapProfiler;
5454
using v8::HeapSpaceStatistics;
5555
using v8::Integer;
5656
using v8::Isolate;
57+
using v8::JustVoid;
5758
using v8::Local;
5859
using v8::Maybe;
5960
using v8::MaybeLocal;
6061
using v8::NewStringType;
62+
using v8::Nothing;
6163
using v8::Number;
6264
using v8::Object;
6365
using v8::ObjectTemplate;
@@ -1590,54 +1592,66 @@ Local<Value> Environment::GetNow() {
15901592
return Number::New(isolate(), static_cast<double>(now));
15911593
}
15921594

1593-
void CollectExceptionInfo(Environment* env,
1594-
Local<Object> obj,
1595-
int errorno,
1596-
const char* err_string,
1597-
const char* syscall,
1598-
const char* message,
1599-
const char* path,
1600-
const char* dest) {
1601-
obj->Set(env->context(),
1602-
env->errno_string(),
1603-
Integer::New(env->isolate(), errorno)).Check();
1604-
1605-
obj->Set(env->context(), env->code_string(),
1606-
OneByteString(env->isolate(), err_string)).Check();
1607-
1608-
if (message != nullptr) {
1609-
obj->Set(env->context(), env->message_string(),
1610-
OneByteString(env->isolate(), message)).Check();
1595+
Maybe<void> CollectExceptionInfo(Environment* env,
1596+
Local<Object> obj,
1597+
int errorno,
1598+
const char* err_string,
1599+
const char* syscall,
1600+
const char* message,
1601+
const char* path,
1602+
const char* dest) {
1603+
if (obj->Set(env->context(),
1604+
env->errno_string(),
1605+
Integer::New(env->isolate(), errorno))
1606+
.IsNothing() ||
1607+
obj->Set(env->context(),
1608+
env->code_string(),
1609+
OneByteString(env->isolate(), err_string))
1610+
.IsNothing() ||
1611+
(message != nullptr && obj->Set(env->context(),
1612+
env->message_string(),
1613+
OneByteString(env->isolate(), message))
1614+
.IsNothing())) {
1615+
return Nothing<void>();
16111616
}
16121617

16131618
Local<Value> path_buffer;
16141619
if (path != nullptr) {
1615-
path_buffer =
1616-
Buffer::Copy(env->isolate(), path, strlen(path)).ToLocalChecked();
1617-
obj->Set(env->context(), env->path_string(), path_buffer).Check();
1620+
if (!Buffer::Copy(env->isolate(), path, strlen(path))
1621+
.ToLocal(&path_buffer) ||
1622+
obj->Set(env->context(), env->path_string(), path_buffer).IsNothing()) {
1623+
return Nothing<void>();
1624+
}
16181625
}
16191626

16201627
Local<Value> dest_buffer;
16211628
if (dest != nullptr) {
1622-
dest_buffer =
1623-
Buffer::Copy(env->isolate(), dest, strlen(dest)).ToLocalChecked();
1624-
obj->Set(env->context(), env->dest_string(), dest_buffer).Check();
1629+
if (!Buffer::Copy(env->isolate(), dest, strlen(dest))
1630+
.ToLocal(&dest_buffer) ||
1631+
obj->Set(env->context(), env->dest_string(), dest_buffer).IsNothing()) {
1632+
return Nothing<void>();
1633+
}
16251634
}
16261635

16271636
if (syscall != nullptr) {
1628-
obj->Set(env->context(), env->syscall_string(),
1629-
OneByteString(env->isolate(), syscall)).Check();
1637+
if (obj->Set(env->context(),
1638+
env->syscall_string(),
1639+
OneByteString(env->isolate(), syscall))
1640+
.IsNothing()) {
1641+
return Nothing<void>();
1642+
}
16301643
}
1644+
1645+
return JustVoid();
16311646
}
16321647

1633-
void Environment::CollectUVExceptionInfo(Local<Value> object,
1634-
int errorno,
1635-
const char* syscall,
1636-
const char* message,
1637-
const char* path,
1638-
const char* dest) {
1639-
if (!object->IsObject() || errorno == 0)
1640-
return;
1648+
Maybe<void> Environment::CollectUVExceptionInfo(Local<Value> object,
1649+
int errorno,
1650+
const char* syscall,
1651+
const char* message,
1652+
const char* path,
1653+
const char* dest) {
1654+
if (!object->IsObject() || errorno == 0) return JustVoid();
16411655

16421656
Local<Object> obj = object.As<Object>();
16431657
const char* err_string = uv_err_name(errorno);
@@ -1646,7 +1660,7 @@ void Environment::CollectUVExceptionInfo(Local<Value> object,
16461660
message = uv_strerror(errorno);
16471661
}
16481662

1649-
CollectExceptionInfo(
1663+
return CollectExceptionInfo(
16501664
this, obj, errorno, err_string, syscall, message, path, dest);
16511665
}
16521666

src/env.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -767,12 +767,12 @@ class Environment final : public MemoryRetainer {
767767

768768
inline performance::PerformanceState* performance_state();
769769

770-
void CollectUVExceptionInfo(v8::Local<v8::Value> context,
771-
int errorno,
772-
const char* syscall = nullptr,
773-
const char* message = nullptr,
774-
const char* path = nullptr,
775-
const char* dest = nullptr);
770+
v8::Maybe<void> CollectUVExceptionInfo(v8::Local<v8::Value> context,
771+
int errorno,
772+
const char* syscall = nullptr,
773+
const char* message = nullptr,
774+
const char* path = nullptr,
775+
const char* dest = nullptr);
776776

777777
// If this flag is set, calls into JS (if they would be observable
778778
// from userland) must be avoided. This flag does not indicate whether

src/node_binding.cc

+8-6
Original file line numberDiff line numberDiff line change
@@ -685,8 +685,9 @@ void GetLinkedBinding(const FunctionCallbackInfo<Value>& args) {
685685

686686
Local<Object> module = Object::New(env->isolate());
687687
Local<Object> exports = Object::New(env->isolate());
688-
Local<String> exports_prop = env->exports_string();
689-
module->Set(env->context(), exports_prop, exports).Check();
688+
if (module->Set(env->context(), env->exports_string(), exports).IsNothing()) {
689+
return;
690+
}
690691

691692
if (mod->nm_context_register_func != nullptr) {
692693
mod->nm_context_register_func(
@@ -698,10 +699,11 @@ void GetLinkedBinding(const FunctionCallbackInfo<Value>& args) {
698699
env, "Linked binding has no declared entry point.");
699700
}
700701

701-
auto effective_exports =
702-
module->Get(env->context(), exports_prop).ToLocalChecked();
703-
704-
args.GetReturnValue().Set(effective_exports);
702+
Local<Value> effective_exports;
703+
if (module->Get(env->context(), env->exports_string())
704+
.ToLocal(&effective_exports)) {
705+
args.GetReturnValue().Set(effective_exports);
706+
}
705707
}
706708

707709
// Call built-in bindings' _register_<module name> function to

src/node_errors.cc

+6-3
Original file line numberDiff line numberDiff line change
@@ -1215,9 +1215,12 @@ void TriggerUncaughtException(Isolate* isolate,
12151215
// monkey-patchable.
12161216
Local<Object> process_object = env->process_object();
12171217
Local<String> fatal_exception_string = env->fatal_exception_string();
1218-
Local<Value> fatal_exception_function =
1219-
process_object->Get(env->context(),
1220-
fatal_exception_string).ToLocalChecked();
1218+
Local<Value> fatal_exception_function;
1219+
if (!process_object->Get(env->context(), fatal_exception_string)
1220+
.ToLocal(&fatal_exception_function)) {
1221+
// V8 will have scheduled a superseding error to throw
1222+
return;
1223+
}
12211224
// If the exception happens before process._fatalException is attached
12221225
// during bootstrap, or if the user has patched it incorrectly, exit
12231226
// the current Node.js instance.

src/node_os.cc

+23-19
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ static void GetHostname(const FunctionCallbackInfo<Value>& args) {
6767

6868
if (r != 0) {
6969
CHECK_GE(args.Length(), 1);
70-
env->CollectUVExceptionInfo(args[args.Length() - 1], r,
71-
"uv_os_gethostname");
72-
return args.GetReturnValue().SetUndefined();
70+
USE(env->CollectUVExceptionInfo(
71+
args[args.Length() - 1], r, "uv_os_gethostname"));
72+
return;
7373
}
7474

7575
Local<Value> ret;
@@ -85,8 +85,9 @@ static void GetOSInformation(const FunctionCallbackInfo<Value>& args) {
8585

8686
if (err != 0) {
8787
CHECK_GE(args.Length(), 1);
88-
env->CollectUVExceptionInfo(args[args.Length() - 1], err, "uv_os_uname");
89-
return args.GetReturnValue().SetUndefined();
88+
USE(env->CollectUVExceptionInfo(
89+
args[args.Length() - 1], err, "uv_os_uname"));
90+
return;
9091
}
9192

9293
// [sysname, version, release, machine]
@@ -159,8 +160,8 @@ static void GetUptime(const FunctionCallbackInfo<Value>& args) {
159160
double uptime;
160161
int err = uv_uptime(&uptime);
161162
if (err != 0) {
162-
env->CollectUVExceptionInfo(args[args.Length() - 1], err, "uv_uptime");
163-
return args.GetReturnValue().SetUndefined();
163+
USE(env->CollectUVExceptionInfo(args[args.Length() - 1], err, "uv_uptime"));
164+
return;
164165
}
165166

166167
args.GetReturnValue().Set(uptime);
@@ -189,14 +190,13 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo<Value>& args) {
189190

190191
int err = uv_interface_addresses(&interfaces, &count);
191192

192-
if (err == UV_ENOSYS)
193-
return args.GetReturnValue().SetUndefined();
193+
if (err == UV_ENOSYS) return;
194194

195195
if (err) {
196196
CHECK_GE(args.Length(), 1);
197-
env->CollectUVExceptionInfo(args[args.Length() - 1], errno,
198-
"uv_interface_addresses");
199-
return args.GetReturnValue().SetUndefined();
197+
USE(env->CollectUVExceptionInfo(
198+
args[args.Length() - 1], errno, "uv_interface_addresses"));
199+
return;
200200
}
201201

202202
Local<Value> no_scope_id = Integer::New(isolate, -1);
@@ -267,8 +267,9 @@ static void GetHomeDirectory(const FunctionCallbackInfo<Value>& args) {
267267

268268
if (err) {
269269
CHECK_GE(args.Length(), 1);
270-
env->CollectUVExceptionInfo(args[args.Length() - 1], err, "uv_os_homedir");
271-
return args.GetReturnValue().SetUndefined();
270+
USE(env->CollectUVExceptionInfo(
271+
args[args.Length() - 1], err, "uv_os_homedir"));
272+
return;
272273
}
273274

274275
Local<String> home;
@@ -299,9 +300,9 @@ static void GetUserInfo(const FunctionCallbackInfo<Value>& args) {
299300

300301
if (const int err = uv_os_get_passwd(&pwd)) {
301302
CHECK_GE(args.Length(), 2);
302-
env->CollectUVExceptionInfo(args[args.Length() - 1], err,
303-
"uv_os_get_passwd");
304-
return args.GetReturnValue().SetUndefined();
303+
USE(env->CollectUVExceptionInfo(
304+
args[args.Length() - 1], err, "uv_os_get_passwd"));
305+
return;
305306
}
306307

307308
auto free_passwd = OnScopeLeave([&] { uv_os_free_passwd(&pwd); });
@@ -371,7 +372,10 @@ static void SetPriority(const FunctionCallbackInfo<Value>& args) {
371372

372373
if (err) {
373374
CHECK(args[2]->IsObject());
374-
env->CollectUVExceptionInfo(args[2], err, "uv_os_setpriority");
375+
if (env->CollectUVExceptionInfo(args[2], err, "uv_os_setpriority")
376+
.IsNothing()) {
377+
return;
378+
}
375379
}
376380

377381
args.GetReturnValue().Set(err);
@@ -390,7 +394,7 @@ static void GetPriority(const FunctionCallbackInfo<Value>& args) {
390394

391395
if (err) {
392396
CHECK(args[1]->IsObject());
393-
env->CollectUVExceptionInfo(args[1], err, "uv_os_getpriority");
397+
USE(env->CollectUVExceptionInfo(args[1], err, "uv_os_getpriority"));
394398
return;
395399
}
396400

src/node_wasi.cc

+34-10
Original file line numberDiff line numberDiff line change
@@ -134,20 +134,37 @@ void WASI::New(const FunctionCallbackInfo<Value>& args) {
134134

135135
Local<Array> stdio = args[3].As<Array>();
136136
CHECK_EQ(stdio->Length(), 3);
137-
options.in = stdio->Get(context, 0).ToLocalChecked()->
138-
Int32Value(context).FromJust();
139-
options.out = stdio->Get(context, 1).ToLocalChecked()->
140-
Int32Value(context).FromJust();
141-
options.err = stdio->Get(context, 2).ToLocalChecked()->
142-
Int32Value(context).FromJust();
137+
138+
Local<Value> val;
139+
int32_t tmp;
140+
if (!stdio->Get(context, 0).ToLocal(&val) ||
141+
!val->Int32Value(context).To(&tmp)) {
142+
return;
143+
}
144+
options.in = tmp;
145+
146+
if (!stdio->Get(context, 1).ToLocal(&val) ||
147+
!val->Int32Value(context).To(&tmp)) {
148+
return;
149+
}
150+
options.out = tmp;
151+
152+
if (!stdio->Get(context, 2).ToLocal(&val) ||
153+
!val->Int32Value(context).To(&tmp)) {
154+
return;
155+
}
156+
options.err = tmp;
143157

144158
options.fd_table_size = 3;
145159
options.argc = argc;
146160
options.argv =
147161
const_cast<const char**>(argc == 0 ? nullptr : new char*[argc]);
148162

149163
for (uint32_t i = 0; i < argc; i++) {
150-
auto arg = argv->Get(context, i).ToLocalChecked();
164+
Local<Value> arg;
165+
if (!argv->Get(context, i).ToLocal(&arg)) {
166+
return;
167+
}
151168
CHECK(arg->IsString());
152169
node::Utf8Value str(env->isolate(), arg);
153170
options.argv[i] = strdup(*str);
@@ -158,7 +175,10 @@ void WASI::New(const FunctionCallbackInfo<Value>& args) {
158175
const uint32_t envc = env_pairs->Length();
159176
options.envp = const_cast<const char**>(new char*[envc + 1]);
160177
for (uint32_t i = 0; i < envc; i++) {
161-
auto pair = env_pairs->Get(context, i).ToLocalChecked();
178+
Local<Value> pair;
179+
if (!env_pairs->Get(context, i).ToLocal(&pair)) {
180+
return;
181+
}
162182
CHECK(pair->IsString());
163183
node::Utf8Value str(env->isolate(), pair);
164184
options.envp[i] = strdup(*str);
@@ -172,8 +192,12 @@ void WASI::New(const FunctionCallbackInfo<Value>& args) {
172192
options.preopens = Calloc<uvwasi_preopen_t>(options.preopenc);
173193
int index = 0;
174194
for (uint32_t i = 0; i < preopens->Length(); i += 2) {
175-
auto mapped = preopens->Get(context, i).ToLocalChecked();
176-
auto real = preopens->Get(context, i + 1).ToLocalChecked();
195+
Local<Value> mapped;
196+
Local<Value> real;
197+
if (!preopens->Get(context, i).ToLocal(&mapped) ||
198+
!preopens->Get(context, i + 1).ToLocal(&real)) {
199+
return;
200+
}
177201
CHECK(mapped->IsString());
178202
CHECK(real->IsString());
179203
node::Utf8Value mapped_path(env->isolate(), mapped);

src/tty_wrap.cc

+1-2
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,7 @@ void TTYWrap::New(const FunctionCallbackInfo<Value>& args) {
136136
int err = 0;
137137
new TTYWrap(env, args.This(), fd, &err);
138138
if (err != 0) {
139-
env->CollectUVExceptionInfo(args[1], err, "uv_tty_init");
140-
args.GetReturnValue().SetUndefined();
139+
USE(env->CollectUVExceptionInfo(args[1], err, "uv_tty_init"));
141140
}
142141
}
143142

src/udp_wrap.cc

+4-4
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,8 @@ void UDPWrap::BufferSize(const FunctionCallbackInfo<Value>& args) {
384384
"uv_send_buffer_size";
385385

386386
if (!args[0]->IsInt32()) {
387-
env->CollectUVExceptionInfo(args[2], UV_EINVAL, uv_func_name);
388-
return args.GetReturnValue().SetUndefined();
387+
USE(env->CollectUVExceptionInfo(args[2], UV_EINVAL, uv_func_name));
388+
return;
389389
}
390390

391391
uv_handle_t* handle = reinterpret_cast<uv_handle_t*>(&wrap->handle_);
@@ -398,8 +398,8 @@ void UDPWrap::BufferSize(const FunctionCallbackInfo<Value>& args) {
398398
err = uv_send_buffer_size(handle, &size);
399399

400400
if (err != 0) {
401-
env->CollectUVExceptionInfo(args[2], err, uv_func_name);
402-
return args.GetReturnValue().SetUndefined();
401+
USE(env->CollectUVExceptionInfo(args[2], err, uv_func_name));
402+
return;
403403
}
404404

405405
args.GetReturnValue().Set(size);

0 commit comments

Comments
 (0)