mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
src: make more error handling improvements
PR-URL: https://github.com/nodejs/node/pull/57262 Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
This commit is contained in:
parent
2cff256065
commit
52ac44888d
8 changed files with 131 additions and 85 deletions
84
src/env.cc
84
src/env.cc
|
@ -54,10 +54,12 @@ using v8::HeapProfiler;
|
|||
using v8::HeapSpaceStatistics;
|
||||
using v8::Integer;
|
||||
using v8::Isolate;
|
||||
using v8::JustVoid;
|
||||
using v8::Local;
|
||||
using v8::Maybe;
|
||||
using v8::MaybeLocal;
|
||||
using v8::NewStringType;
|
||||
using v8::Nothing;
|
||||
using v8::Number;
|
||||
using v8::Object;
|
||||
using v8::ObjectTemplate;
|
||||
|
@ -1590,54 +1592,66 @@ Local<Value> Environment::GetNow() {
|
|||
return Number::New(isolate(), static_cast<double>(now));
|
||||
}
|
||||
|
||||
void CollectExceptionInfo(Environment* env,
|
||||
Local<Object> obj,
|
||||
int errorno,
|
||||
const char* err_string,
|
||||
const char* syscall,
|
||||
const char* message,
|
||||
const char* path,
|
||||
const char* dest) {
|
||||
obj->Set(env->context(),
|
||||
env->errno_string(),
|
||||
Integer::New(env->isolate(), errorno)).Check();
|
||||
|
||||
obj->Set(env->context(), env->code_string(),
|
||||
OneByteString(env->isolate(), err_string)).Check();
|
||||
|
||||
if (message != nullptr) {
|
||||
obj->Set(env->context(), env->message_string(),
|
||||
OneByteString(env->isolate(), message)).Check();
|
||||
Maybe<void> CollectExceptionInfo(Environment* env,
|
||||
Local<Object> obj,
|
||||
int errorno,
|
||||
const char* err_string,
|
||||
const char* syscall,
|
||||
const char* message,
|
||||
const char* path,
|
||||
const char* dest) {
|
||||
if (obj->Set(env->context(),
|
||||
env->errno_string(),
|
||||
Integer::New(env->isolate(), errorno))
|
||||
.IsNothing() ||
|
||||
obj->Set(env->context(),
|
||||
env->code_string(),
|
||||
OneByteString(env->isolate(), err_string))
|
||||
.IsNothing() ||
|
||||
(message != nullptr && obj->Set(env->context(),
|
||||
env->message_string(),
|
||||
OneByteString(env->isolate(), message))
|
||||
.IsNothing())) {
|
||||
return Nothing<void>();
|
||||
}
|
||||
|
||||
Local<Value> path_buffer;
|
||||
if (path != nullptr) {
|
||||
path_buffer =
|
||||
Buffer::Copy(env->isolate(), path, strlen(path)).ToLocalChecked();
|
||||
obj->Set(env->context(), env->path_string(), path_buffer).Check();
|
||||
if (!Buffer::Copy(env->isolate(), path, strlen(path))
|
||||
.ToLocal(&path_buffer) ||
|
||||
obj->Set(env->context(), env->path_string(), path_buffer).IsNothing()) {
|
||||
return Nothing<void>();
|
||||
}
|
||||
}
|
||||
|
||||
Local<Value> dest_buffer;
|
||||
if (dest != nullptr) {
|
||||
dest_buffer =
|
||||
Buffer::Copy(env->isolate(), dest, strlen(dest)).ToLocalChecked();
|
||||
obj->Set(env->context(), env->dest_string(), dest_buffer).Check();
|
||||
if (!Buffer::Copy(env->isolate(), dest, strlen(dest))
|
||||
.ToLocal(&dest_buffer) ||
|
||||
obj->Set(env->context(), env->dest_string(), dest_buffer).IsNothing()) {
|
||||
return Nothing<void>();
|
||||
}
|
||||
}
|
||||
|
||||
if (syscall != nullptr) {
|
||||
obj->Set(env->context(), env->syscall_string(),
|
||||
OneByteString(env->isolate(), syscall)).Check();
|
||||
if (obj->Set(env->context(),
|
||||
env->syscall_string(),
|
||||
OneByteString(env->isolate(), syscall))
|
||||
.IsNothing()) {
|
||||
return Nothing<void>();
|
||||
}
|
||||
}
|
||||
|
||||
return JustVoid();
|
||||
}
|
||||
|
||||
void Environment::CollectUVExceptionInfo(Local<Value> object,
|
||||
int errorno,
|
||||
const char* syscall,
|
||||
const char* message,
|
||||
const char* path,
|
||||
const char* dest) {
|
||||
if (!object->IsObject() || errorno == 0)
|
||||
return;
|
||||
Maybe<void> Environment::CollectUVExceptionInfo(Local<Value> object,
|
||||
int errorno,
|
||||
const char* syscall,
|
||||
const char* message,
|
||||
const char* path,
|
||||
const char* dest) {
|
||||
if (!object->IsObject() || errorno == 0) return JustVoid();
|
||||
|
||||
Local<Object> obj = object.As<Object>();
|
||||
const char* err_string = uv_err_name(errorno);
|
||||
|
@ -1646,7 +1660,7 @@ void Environment::CollectUVExceptionInfo(Local<Value> object,
|
|||
message = uv_strerror(errorno);
|
||||
}
|
||||
|
||||
CollectExceptionInfo(
|
||||
return CollectExceptionInfo(
|
||||
this, obj, errorno, err_string, syscall, message, path, dest);
|
||||
}
|
||||
|
||||
|
|
12
src/env.h
12
src/env.h
|
@ -767,12 +767,12 @@ class Environment final : public MemoryRetainer {
|
|||
|
||||
inline performance::PerformanceState* performance_state();
|
||||
|
||||
void CollectUVExceptionInfo(v8::Local<v8::Value> context,
|
||||
int errorno,
|
||||
const char* syscall = nullptr,
|
||||
const char* message = nullptr,
|
||||
const char* path = nullptr,
|
||||
const char* dest = nullptr);
|
||||
v8::Maybe<void> CollectUVExceptionInfo(v8::Local<v8::Value> context,
|
||||
int errorno,
|
||||
const char* syscall = nullptr,
|
||||
const char* message = nullptr,
|
||||
const char* path = nullptr,
|
||||
const char* dest = nullptr);
|
||||
|
||||
// If this flag is set, calls into JS (if they would be observable
|
||||
// from userland) must be avoided. This flag does not indicate whether
|
||||
|
|
|
@ -685,8 +685,9 @@ void GetLinkedBinding(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
Local<Object> module = Object::New(env->isolate());
|
||||
Local<Object> exports = Object::New(env->isolate());
|
||||
Local<String> exports_prop = env->exports_string();
|
||||
module->Set(env->context(), exports_prop, exports).Check();
|
||||
if (module->Set(env->context(), env->exports_string(), exports).IsNothing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mod->nm_context_register_func != nullptr) {
|
||||
mod->nm_context_register_func(
|
||||
|
@ -698,10 +699,11 @@ void GetLinkedBinding(const FunctionCallbackInfo<Value>& args) {
|
|||
env, "Linked binding has no declared entry point.");
|
||||
}
|
||||
|
||||
auto effective_exports =
|
||||
module->Get(env->context(), exports_prop).ToLocalChecked();
|
||||
|
||||
args.GetReturnValue().Set(effective_exports);
|
||||
Local<Value> effective_exports;
|
||||
if (module->Get(env->context(), env->exports_string())
|
||||
.ToLocal(&effective_exports)) {
|
||||
args.GetReturnValue().Set(effective_exports);
|
||||
}
|
||||
}
|
||||
|
||||
// Call built-in bindings' _register_<module name> function to
|
||||
|
|
|
@ -1215,9 +1215,12 @@ void TriggerUncaughtException(Isolate* isolate,
|
|||
// monkey-patchable.
|
||||
Local<Object> process_object = env->process_object();
|
||||
Local<String> fatal_exception_string = env->fatal_exception_string();
|
||||
Local<Value> fatal_exception_function =
|
||||
process_object->Get(env->context(),
|
||||
fatal_exception_string).ToLocalChecked();
|
||||
Local<Value> fatal_exception_function;
|
||||
if (!process_object->Get(env->context(), fatal_exception_string)
|
||||
.ToLocal(&fatal_exception_function)) {
|
||||
// V8 will have scheduled a superseding error to throw
|
||||
return;
|
||||
}
|
||||
// If the exception happens before process._fatalException is attached
|
||||
// during bootstrap, or if the user has patched it incorrectly, exit
|
||||
// the current Node.js instance.
|
||||
|
|
|
@ -67,9 +67,9 @@ static void GetHostname(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
if (r != 0) {
|
||||
CHECK_GE(args.Length(), 1);
|
||||
env->CollectUVExceptionInfo(args[args.Length() - 1], r,
|
||||
"uv_os_gethostname");
|
||||
return args.GetReturnValue().SetUndefined();
|
||||
USE(env->CollectUVExceptionInfo(
|
||||
args[args.Length() - 1], r, "uv_os_gethostname"));
|
||||
return;
|
||||
}
|
||||
|
||||
Local<Value> ret;
|
||||
|
@ -85,8 +85,9 @@ static void GetOSInformation(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
if (err != 0) {
|
||||
CHECK_GE(args.Length(), 1);
|
||||
env->CollectUVExceptionInfo(args[args.Length() - 1], err, "uv_os_uname");
|
||||
return args.GetReturnValue().SetUndefined();
|
||||
USE(env->CollectUVExceptionInfo(
|
||||
args[args.Length() - 1], err, "uv_os_uname"));
|
||||
return;
|
||||
}
|
||||
|
||||
// [sysname, version, release, machine]
|
||||
|
@ -159,8 +160,8 @@ static void GetUptime(const FunctionCallbackInfo<Value>& args) {
|
|||
double uptime;
|
||||
int err = uv_uptime(&uptime);
|
||||
if (err != 0) {
|
||||
env->CollectUVExceptionInfo(args[args.Length() - 1], err, "uv_uptime");
|
||||
return args.GetReturnValue().SetUndefined();
|
||||
USE(env->CollectUVExceptionInfo(args[args.Length() - 1], err, "uv_uptime"));
|
||||
return;
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(uptime);
|
||||
|
@ -189,14 +190,13 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
int err = uv_interface_addresses(&interfaces, &count);
|
||||
|
||||
if (err == UV_ENOSYS)
|
||||
return args.GetReturnValue().SetUndefined();
|
||||
if (err == UV_ENOSYS) return;
|
||||
|
||||
if (err) {
|
||||
CHECK_GE(args.Length(), 1);
|
||||
env->CollectUVExceptionInfo(args[args.Length() - 1], errno,
|
||||
"uv_interface_addresses");
|
||||
return args.GetReturnValue().SetUndefined();
|
||||
USE(env->CollectUVExceptionInfo(
|
||||
args[args.Length() - 1], errno, "uv_interface_addresses"));
|
||||
return;
|
||||
}
|
||||
|
||||
Local<Value> no_scope_id = Integer::New(isolate, -1);
|
||||
|
@ -267,8 +267,9 @@ static void GetHomeDirectory(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
if (err) {
|
||||
CHECK_GE(args.Length(), 1);
|
||||
env->CollectUVExceptionInfo(args[args.Length() - 1], err, "uv_os_homedir");
|
||||
return args.GetReturnValue().SetUndefined();
|
||||
USE(env->CollectUVExceptionInfo(
|
||||
args[args.Length() - 1], err, "uv_os_homedir"));
|
||||
return;
|
||||
}
|
||||
|
||||
Local<String> home;
|
||||
|
@ -299,9 +300,9 @@ static void GetUserInfo(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
if (const int err = uv_os_get_passwd(&pwd)) {
|
||||
CHECK_GE(args.Length(), 2);
|
||||
env->CollectUVExceptionInfo(args[args.Length() - 1], err,
|
||||
"uv_os_get_passwd");
|
||||
return args.GetReturnValue().SetUndefined();
|
||||
USE(env->CollectUVExceptionInfo(
|
||||
args[args.Length() - 1], err, "uv_os_get_passwd"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto free_passwd = OnScopeLeave([&] { uv_os_free_passwd(&pwd); });
|
||||
|
@ -371,7 +372,10 @@ static void SetPriority(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
if (err) {
|
||||
CHECK(args[2]->IsObject());
|
||||
env->CollectUVExceptionInfo(args[2], err, "uv_os_setpriority");
|
||||
if (env->CollectUVExceptionInfo(args[2], err, "uv_os_setpriority")
|
||||
.IsNothing()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(err);
|
||||
|
@ -390,7 +394,7 @@ static void GetPriority(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
if (err) {
|
||||
CHECK(args[1]->IsObject());
|
||||
env->CollectUVExceptionInfo(args[1], err, "uv_os_getpriority");
|
||||
USE(env->CollectUVExceptionInfo(args[1], err, "uv_os_getpriority"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -134,12 +134,26 @@ void WASI::New(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
Local<Array> stdio = args[3].As<Array>();
|
||||
CHECK_EQ(stdio->Length(), 3);
|
||||
options.in = stdio->Get(context, 0).ToLocalChecked()->
|
||||
Int32Value(context).FromJust();
|
||||
options.out = stdio->Get(context, 1).ToLocalChecked()->
|
||||
Int32Value(context).FromJust();
|
||||
options.err = stdio->Get(context, 2).ToLocalChecked()->
|
||||
Int32Value(context).FromJust();
|
||||
|
||||
Local<Value> val;
|
||||
int32_t tmp;
|
||||
if (!stdio->Get(context, 0).ToLocal(&val) ||
|
||||
!val->Int32Value(context).To(&tmp)) {
|
||||
return;
|
||||
}
|
||||
options.in = tmp;
|
||||
|
||||
if (!stdio->Get(context, 1).ToLocal(&val) ||
|
||||
!val->Int32Value(context).To(&tmp)) {
|
||||
return;
|
||||
}
|
||||
options.out = tmp;
|
||||
|
||||
if (!stdio->Get(context, 2).ToLocal(&val) ||
|
||||
!val->Int32Value(context).To(&tmp)) {
|
||||
return;
|
||||
}
|
||||
options.err = tmp;
|
||||
|
||||
options.fd_table_size = 3;
|
||||
options.argc = argc;
|
||||
|
@ -147,7 +161,10 @@ void WASI::New(const FunctionCallbackInfo<Value>& args) {
|
|||
const_cast<const char**>(argc == 0 ? nullptr : new char*[argc]);
|
||||
|
||||
for (uint32_t i = 0; i < argc; i++) {
|
||||
auto arg = argv->Get(context, i).ToLocalChecked();
|
||||
Local<Value> arg;
|
||||
if (!argv->Get(context, i).ToLocal(&arg)) {
|
||||
return;
|
||||
}
|
||||
CHECK(arg->IsString());
|
||||
node::Utf8Value str(env->isolate(), arg);
|
||||
options.argv[i] = strdup(*str);
|
||||
|
@ -158,7 +175,10 @@ void WASI::New(const FunctionCallbackInfo<Value>& args) {
|
|||
const uint32_t envc = env_pairs->Length();
|
||||
options.envp = const_cast<const char**>(new char*[envc + 1]);
|
||||
for (uint32_t i = 0; i < envc; i++) {
|
||||
auto pair = env_pairs->Get(context, i).ToLocalChecked();
|
||||
Local<Value> pair;
|
||||
if (!env_pairs->Get(context, i).ToLocal(&pair)) {
|
||||
return;
|
||||
}
|
||||
CHECK(pair->IsString());
|
||||
node::Utf8Value str(env->isolate(), pair);
|
||||
options.envp[i] = strdup(*str);
|
||||
|
@ -172,8 +192,12 @@ void WASI::New(const FunctionCallbackInfo<Value>& args) {
|
|||
options.preopens = Calloc<uvwasi_preopen_t>(options.preopenc);
|
||||
int index = 0;
|
||||
for (uint32_t i = 0; i < preopens->Length(); i += 2) {
|
||||
auto mapped = preopens->Get(context, i).ToLocalChecked();
|
||||
auto real = preopens->Get(context, i + 1).ToLocalChecked();
|
||||
Local<Value> mapped;
|
||||
Local<Value> real;
|
||||
if (!preopens->Get(context, i).ToLocal(&mapped) ||
|
||||
!preopens->Get(context, i + 1).ToLocal(&real)) {
|
||||
return;
|
||||
}
|
||||
CHECK(mapped->IsString());
|
||||
CHECK(real->IsString());
|
||||
node::Utf8Value mapped_path(env->isolate(), mapped);
|
||||
|
|
|
@ -136,8 +136,7 @@ void TTYWrap::New(const FunctionCallbackInfo<Value>& args) {
|
|||
int err = 0;
|
||||
new TTYWrap(env, args.This(), fd, &err);
|
||||
if (err != 0) {
|
||||
env->CollectUVExceptionInfo(args[1], err, "uv_tty_init");
|
||||
args.GetReturnValue().SetUndefined();
|
||||
USE(env->CollectUVExceptionInfo(args[1], err, "uv_tty_init"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -384,8 +384,8 @@ void UDPWrap::BufferSize(const FunctionCallbackInfo<Value>& args) {
|
|||
"uv_send_buffer_size";
|
||||
|
||||
if (!args[0]->IsInt32()) {
|
||||
env->CollectUVExceptionInfo(args[2], UV_EINVAL, uv_func_name);
|
||||
return args.GetReturnValue().SetUndefined();
|
||||
USE(env->CollectUVExceptionInfo(args[2], UV_EINVAL, uv_func_name));
|
||||
return;
|
||||
}
|
||||
|
||||
uv_handle_t* handle = reinterpret_cast<uv_handle_t*>(&wrap->handle_);
|
||||
|
@ -398,8 +398,8 @@ void UDPWrap::BufferSize(const FunctionCallbackInfo<Value>& args) {
|
|||
err = uv_send_buffer_size(handle, &size);
|
||||
|
||||
if (err != 0) {
|
||||
env->CollectUVExceptionInfo(args[2], err, uv_func_name);
|
||||
return args.GetReturnValue().SetUndefined();
|
||||
USE(env->CollectUVExceptionInfo(args[2], err, uv_func_name));
|
||||
return;
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(size);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue