Skip to content

Commit

Permalink
src: improve error handling in multiple files
Browse files Browse the repository at this point in the history
PR-URL: #56962
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
  • Loading branch information
jasnell authored and targos committed Feb 25, 2025
1 parent 4b02fdc commit 5414eb4
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 178 deletions.
34 changes: 22 additions & 12 deletions src/node_i18n.cc
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,15 @@ namespace {

template <typename T>
MaybeLocal<Object> ToBufferEndian(Environment* env, MaybeStackBuffer<T>* buf) {
MaybeLocal<Object> ret = Buffer::New(env, buf);
if (ret.IsEmpty())
return ret;
Local<Object> ret;
if (!Buffer::New(env, buf).ToLocal(&ret)) {
return {};
}

static_assert(sizeof(T) == 1 || sizeof(T) == 2,
"Currently only one- or two-byte buffers are supported");
if constexpr (sizeof(T) > 1 && IsBigEndian()) {
SPREAD_BUFFER_ARG(ret.ToLocalChecked(), retbuf);
SPREAD_BUFFER_ARG(ret, retbuf);
CHECK(nbytes::SwapBytes16(retbuf_data, retbuf_length));
}

Expand Down Expand Up @@ -317,19 +318,22 @@ void Transcode(const FunctionCallbackInfo<Value>&args) {
status = U_ILLEGAL_ARGUMENT_ERROR;
}

if (result.IsEmpty())
return args.GetReturnValue().Set(status);
Local<Object> res;
if (result.ToLocal(&res)) {
return args.GetReturnValue().Set(res);
}

return args.GetReturnValue().Set(result.ToLocalChecked());
return args.GetReturnValue().Set(status);
}

void ICUErrorName(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
CHECK(args[0]->IsInt32());
UErrorCode status = static_cast<UErrorCode>(args[0].As<Int32>()->Value());
args.GetReturnValue().Set(
String::NewFromUtf8(env->isolate(),
u_errorName(status)).ToLocalChecked());
Local<Value> res;
if (String::NewFromUtf8(env->isolate(), u_errorName(status)).ToLocal(&res)) {
args.GetReturnValue().Set(res);
}
}

} // anonymous namespace
Expand Down Expand Up @@ -390,7 +394,10 @@ void ConverterObject::Create(const FunctionCallbackInfo<Value>& args) {

CHECK_GE(args.Length(), 2);
Utf8Value label(env->isolate(), args[0]);
int flags = args[1]->Uint32Value(env->context()).ToChecked();
uint32_t flags;
if (!args[1]->Uint32Value(env->context()).To(&flags)) {
return;
}
bool fatal =
(flags & CONVERTER_FLAGS_FATAL) == CONVERTER_FLAGS_FATAL;

Expand Down Expand Up @@ -430,7 +437,10 @@ void ConverterObject::Decode(const FunctionCallbackInfo<Value>& args) {
}

ArrayBufferViewContents<char> input(args[1]);
int flags = args[2]->Uint32Value(env->context()).ToChecked();
uint32_t flags;
if (!args[2]->Uint32Value(env->context()).To(&flags)) {
return;
}

CHECK(args[3]->IsString());
Local<String> from_encoding = args[3].As<String>();
Expand Down
14 changes: 7 additions & 7 deletions src/node_messaging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1150,16 +1150,16 @@ void MessagePort::ReceiveMessage(const FunctionCallbackInfo<Value>& args) {
MessagePort* port = Unwrap<MessagePort>(args[0].As<Object>());
if (port == nullptr) {
// Return 'no messages' for a closed port.
args.GetReturnValue().Set(
Environment::GetCurrent(args)->no_message_symbol());
args.GetReturnValue().Set(env->no_message_symbol());
return;
}

MaybeLocal<Value> payload =
port->ReceiveMessage(port->object()->GetCreationContextChecked(),
MessageProcessingMode::kForceReadMessages);
if (!payload.IsEmpty())
args.GetReturnValue().Set(payload.ToLocalChecked());
Local<Value> payload;
if (port->ReceiveMessage(port->object()->GetCreationContextChecked(),
MessageProcessingMode::kForceReadMessages)
.ToLocal(&payload)) {
args.GetReturnValue().Set(payload);
}
}

void MessagePort::MoveToContext(const FunctionCallbackInfo<Value>& args) {
Expand Down
39 changes: 22 additions & 17 deletions src/node_modules.cc
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,10 @@ void BindingData::GetNearestParentPackageJSONType(
return;
}

Local<Value> value =
ToV8Value(realm->context(), package_json->type).ToLocalChecked();
args.GetReturnValue().Set(value);
Local<Value> value;
if (ToV8Value(realm->context(), package_json->type).ToLocal(&value)) {
args.GetReturnValue().Set(value);
}
}

void BindingData::GetPackageScopeConfig(
Expand Down Expand Up @@ -462,12 +463,11 @@ void BindingData::GetPackageScopeConfig(
auto package_json_url_as_path =
url::FileURLToPath(realm->env(), *package_json_url);
CHECK(package_json_url_as_path);
return args.GetReturnValue().Set(
String::NewFromUtf8(realm->isolate(),
package_json_url_as_path->c_str(),
NewStringType::kNormal,
package_json_url_as_path->size())
.ToLocalChecked());
Local<Value> ret;
if (ToV8Value(realm->context(), *package_json_url_as_path, realm->isolate())
.ToLocal(&ret)) {
args.GetReturnValue().Set(ret);
}
}

void FlushCompileCache(const FunctionCallbackInfo<Value>& args) {
Expand Down Expand Up @@ -499,11 +499,13 @@ void EnableCompileCache(const FunctionCallbackInfo<Value>& args) {
}
Utf8Value value(isolate, args[0]);
CompileCacheEnableResult result = env->EnableCompileCache(*value);
Local<Value> values[] = {
v8::Integer::New(isolate, static_cast<uint8_t>(result.status)),
ToV8Value(context, result.message).ToLocalChecked(),
ToV8Value(context, result.cache_directory).ToLocalChecked()};
args.GetReturnValue().Set(Array::New(isolate, &values[0], arraysize(values)));
Local<Value> values[3];
values[0] = v8::Integer::New(isolate, static_cast<uint8_t>(result.status));
if (ToV8Value(context, result.message).ToLocal(&values[1]) &&
ToV8Value(context, result.cache_directory).ToLocal(&values[2])) {
args.GetReturnValue().Set(
Array::New(isolate, &values[0], arraysize(values)));
}
}

void GetCompileCacheDir(const FunctionCallbackInfo<Value>& args) {
Expand All @@ -514,9 +516,12 @@ void GetCompileCacheDir(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(v8::String::Empty(isolate));
return;
}
args.GetReturnValue().Set(
ToV8Value(context, env->compile_cache_handler()->cache_dir())
.ToLocalChecked());

Local<Value> ret;
if (ToV8Value(context, env->compile_cache_handler()->cache_dir())
.ToLocal(&ret)) {
args.GetReturnValue().Set(ret);
}
}

void GetCompileCacheEntry(const FunctionCallbackInfo<Value>& args) {
Expand Down
22 changes: 13 additions & 9 deletions src/node_options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1364,9 +1364,11 @@ void GetCLIOptionsValues(const FunctionCallbackInfo<Value>& args) {
std::string negated_name =
"--no" + item.first.substr(1, item.first.size());
Local<Value> negated_value = Boolean::New(isolate, !original_value);
Local<Name> negated_name_v8 =
ToV8Value(context, negated_name).ToLocalChecked().As<Name>();
option_names.push_back(negated_name_v8);
Local<Value> negated_name_v8;
if (!ToV8Value(context, negated_name).ToLocal(&negated_name_v8)) {
return;
}
option_names.push_back(negated_name_v8.As<Name>());
option_values.push_back(negated_value);
break;
}
Expand Down Expand Up @@ -1414,9 +1416,11 @@ void GetCLIOptionsValues(const FunctionCallbackInfo<Value>& args) {
UNREACHABLE();
}
CHECK(!value.IsEmpty());
Local<Name> name =
ToV8Value(context, item.first).ToLocalChecked().As<Name>();
option_names.push_back(name);
Local<Value> name;
if (!ToV8Value(context, item.first).ToLocal(&name)) {
return;
}
option_names.push_back(name.As<Name>());
option_values.push_back(value);
}

Expand Down Expand Up @@ -1455,10 +1459,10 @@ void GetCLIOptionsInfo(const FunctionCallbackInfo<Value>& args) {
const auto& option_info = item.second;
auto field = option_info.field;

Local<Name> name =
ToV8Value(context, item.first).ToLocalChecked().As<Name>();
Local<Value> name;
Local<Value> help_text;
if (!ToV8Value(context, option_info.help_text).ToLocal(&help_text)) {
if (!ToV8Value(context, item.first).ToLocal(&name) ||
!ToV8Value(context, option_info.help_text).ToLocal(&help_text)) {
return;
}
constexpr size_t kInfoSize = 4;
Expand Down
13 changes: 7 additions & 6 deletions src/node_process_methods.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,15 @@ static void Cwd(const FunctionCallbackInfo<Value>& args) {
char buf[PATH_MAX_BYTES];
size_t cwd_len = sizeof(buf);
int err = uv_cwd(buf, &cwd_len);
if (err)
if (err) {
return env->ThrowUVException(err, "uv_cwd");
}

Local<String> cwd = String::NewFromUtf8(env->isolate(),
buf,
NewStringType::kNormal,
cwd_len).ToLocalChecked();
args.GetReturnValue().Set(cwd);
Local<String> cwd;
if (String::NewFromUtf8(env->isolate(), buf, NewStringType::kNormal, cwd_len)
.ToLocal(&cwd)) {
args.GetReturnValue().Set(cwd);
}
}

static void Kill(const FunctionCallbackInfo<Value>& args) {
Expand Down
85 changes: 44 additions & 41 deletions src/node_process_object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,20 @@ using v8::Isolate;
using v8::Local;
using v8::MaybeLocal;
using v8::Name;
using v8::NewStringType;
using v8::None;
using v8::Object;
using v8::PropertyCallbackInfo;
using v8::SideEffectType;
using v8::String;
using v8::Value;

static void ProcessTitleGetter(Local<Name> property,
const PropertyCallbackInfo<Value>& info) {
std::string title = GetProcessTitle("node");
info.GetReturnValue().Set(
String::NewFromUtf8(info.GetIsolate(), title.data(),
NewStringType::kNormal, title.size())
.ToLocalChecked());
Local<Value> ret;
auto isolate = info.GetIsolate();
if (ToV8Value(isolate->GetCurrentContext(), title, isolate).ToLocal(&ret)) {
info.GetReturnValue().Set(ret);
}
}

static void ProcessTitleSetter(Local<Name> property,
Expand Down Expand Up @@ -196,28 +195,34 @@ void PatchProcessObject(const FunctionCallbackInfo<Value>& args) {
.FromJust());

// process.argv
process->Set(context,
FIXED_ONE_BYTE_STRING(isolate, "argv"),
ToV8Value(context, env->argv()).ToLocalChecked()).Check();
Local<Value> val;
if (!ToV8Value(context, env->argv()).ToLocal(&val) ||
!process->Set(context, FIXED_ONE_BYTE_STRING(isolate, "argv"), val)
.IsJust()) {
return;
}

// process.execArgv
process->Set(context,
FIXED_ONE_BYTE_STRING(isolate, "execArgv"),
ToV8Value(context, env->exec_argv())
.ToLocalChecked()).Check();
if (!ToV8Value(context, env->exec_argv()).ToLocal(&val) ||
!process->Set(context, FIXED_ONE_BYTE_STRING(isolate, "execArgv"), val)
.IsJust()) {
return;
}

READONLY_PROPERTY(process, "pid",
Integer::New(isolate, uv_os_getpid()));

CHECK(process
->SetNativeDataProperty(context,
FIXED_ONE_BYTE_STRING(isolate, "ppid"),
GetParentProcessId,
nullptr,
Local<Value>(),
None,
SideEffectType::kHasNoSideEffect)
.FromJust());
if (!process
->SetNativeDataProperty(context,
FIXED_ONE_BYTE_STRING(isolate, "ppid"),
GetParentProcessId,
nullptr,
Local<Value>(),
None,
SideEffectType::kHasNoSideEffect)
.IsJust()) {
return;
}

// --security-revert flags
#define V(code, _, __) \
Expand All @@ -230,27 +235,25 @@ void PatchProcessObject(const FunctionCallbackInfo<Value>& args) {
#undef V

// process.execPath
process
->Set(context,
FIXED_ONE_BYTE_STRING(isolate, "execPath"),
String::NewFromUtf8(isolate,
env->exec_path().c_str(),
NewStringType::kInternalized,
env->exec_path().size())
.ToLocalChecked())
.Check();
if (!ToV8Value(context, env->exec_path(), isolate).ToLocal(&val) ||
!process->Set(context, FIXED_ONE_BYTE_STRING(isolate, "execPath"), val)
.IsJust()) {
return;
}

// process.debugPort
CHECK(process
->SetNativeDataProperty(
context,
FIXED_ONE_BYTE_STRING(isolate, "debugPort"),
DebugPortGetter,
env->owns_process_state() ? DebugPortSetter : nullptr,
Local<Value>(),
None,
SideEffectType::kHasNoSideEffect)
.FromJust());
if (!process
->SetNativeDataProperty(
context,
FIXED_ONE_BYTE_STRING(isolate, "debugPort"),
DebugPortGetter,
env->owns_process_state() ? DebugPortSetter : nullptr,
Local<Value>(),
None,
SideEffectType::kHasNoSideEffect)
.IsJust()) {
return;
}

// process.versions
Local<Object> versions = Object::New(isolate);
Expand Down
12 changes: 8 additions & 4 deletions src/node_report.cc
Original file line number Diff line number Diff line change
Expand Up @@ -439,10 +439,14 @@ static Maybe<std::string> ErrorToString(Isolate* isolate,
} else if (!error->IsObject()) {
maybe_str = error->ToString(context);
} else if (error->IsObject()) {
MaybeLocal<Value> stack = error.As<Object>()->Get(
context, FIXED_ONE_BYTE_STRING(isolate, "stack"));
if (!stack.IsEmpty() && stack.ToLocalChecked()->IsString()) {
maybe_str = stack.ToLocalChecked().As<String>();
Local<Value> stack;
if (!error.As<Object>()
->Get(context, FIXED_ONE_BYTE_STRING(isolate, "stack"))
.ToLocal(&stack)) {
return Nothing<std::string>();
}
if (stack->IsString()) {
maybe_str = stack.As<String>();
}
}

Expand Down
Loading

0 comments on commit 5414eb4

Please # to comment.