Skip to content

Commit a1f20ea

Browse files
committed
Update to new error helper signatures in n-api
Update to use new signatures Update copies of n-api files so they match. I've not done a direct copy because more work is needed given that the n-api files now use node internals. I have updated so that they are consistent and will build ok with respect to this specific chaange. I took this approach to minimize the time the wrapper is broken by the breaking change on the n-api side.
1 parent 10ef293 commit a1f20ea

File tree

4 files changed

+126
-22
lines changed

4 files changed

+126
-22
lines changed

napi-inl.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -1452,10 +1452,10 @@ inline Error Error::New(napi_env env) {
14521452
case napi_string_expected:
14531453
case napi_boolean_expected:
14541454
case napi_number_expected:
1455-
status = napi_create_type_error(env, message, &error);
1455+
status = napi_create_type_error(env, nullptr, message, &error);
14561456
break;
14571457
default:
1458-
status = napi_create_error(env, message, &error);
1458+
status = napi_create_error(env, nullptr, message, &error);
14591459
break;
14601460
}
14611461
assert(status == napi_ok);
@@ -1556,7 +1556,7 @@ inline TError Error::New(napi_env env,
15561556
NAPI_THROW_IF_FAILED(env, status, TError());
15571557

15581558
napi_value error;
1559-
status = create_error(env, str, &error);
1559+
status = create_error(env, nullptr, str, &error);
15601560
NAPI_THROW_IF_FAILED(env, status, TError());
15611561

15621562
return TError(env, error);
@@ -2467,7 +2467,7 @@ inline napi_value ObjectWrap<T>::ConstructorCallbackWrapper(
24672467
if (status != napi_ok) return nullptr;
24682468

24692469
if (!isConstructCall) {
2470-
napi_throw_type_error(env, "Class constructors cannot be invoked without 'new'");
2470+
napi_throw_type_error(env, nullptr, "Class constructors cannot be invoked without 'new'");
24712471
return nullptr;
24722472
}
24732473

napi.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1085,7 +1085,7 @@ namespace Napi {
10851085

10861086
protected:
10871087
/// !cond INTERNAL
1088-
typedef napi_status (*create_error_fn)(napi_env envb, napi_value msg, napi_value* result);
1088+
typedef napi_status (*create_error_fn)(napi_env envb, napi_value code, napi_value msg, napi_value* result);
10891089

10901090
template <typename TError>
10911091
static TError New(napi_env env,

src/node_api.cc

+109-14
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
#include "uv.h"
1919
#include "node_api.h"
2020

21+
// to be moved out to external file
22+
#define FIXED_ONE_BYTE_STRING(isolate, string) \
23+
(node::OneByteString((isolate), (string), sizeof(string) - 1))
24+
2125
static
2226
napi_status napi_set_last_error(napi_env env, napi_status error_code,
2327
uint32_t engine_error_code = 0,
@@ -1398,7 +1402,61 @@ napi_status napi_create_symbol(napi_env env,
13981402
return GET_RETURN_STATUS(env);
13991403
}
14001404

1405+
static napi_status set_error_code(napi_env env,
1406+
v8::Local<v8::Value> error,
1407+
napi_value code,
1408+
const char* code_cstring) {
1409+
if ((code != nullptr) || (code_cstring != nullptr)) {
1410+
v8::Isolate* isolate = env->isolate;
1411+
v8::Local<v8::Context> context = isolate->GetCurrentContext();
1412+
v8::Local<v8::Object> err_object = error.As<v8::Object>();
1413+
1414+
v8::Local<v8::Value> code_value = v8impl::V8LocalValueFromJsValue(code);
1415+
if (code != nullptr) {
1416+
code_value = v8impl::V8LocalValueFromJsValue(code);
1417+
RETURN_STATUS_IF_FALSE(env, code_value->IsString(), napi_string_expected);
1418+
} else {
1419+
CHECK_NEW_FROM_UTF8(env, code_value, code_cstring);
1420+
}
1421+
1422+
v8::Local<v8::Name> code_key;
1423+
CHECK_NEW_FROM_UTF8(env, code_key, "code");
1424+
1425+
v8::Maybe<bool> set_maybe = err_object->Set(context, code_key, code_value);
1426+
RETURN_STATUS_IF_FALSE(env,
1427+
set_maybe.FromMaybe(false),
1428+
napi_generic_failure);
1429+
1430+
// now update the name to be "name [code]" where name is the
1431+
// original name and code is the code associated with the Error
1432+
v8::Local<v8::String> name_string;
1433+
CHECK_NEW_FROM_UTF8(env, name_string, "");
1434+
v8::Local<v8::Name> name_key;
1435+
CHECK_NEW_FROM_UTF8(env, name_key, "name");
1436+
1437+
auto maybe_name = err_object->Get(context, name_key);
1438+
if (!maybe_name.IsEmpty()) {
1439+
v8::Local<v8::Value> name = maybe_name.ToLocalChecked();
1440+
if (name->IsString()) {
1441+
name_string = v8::String::Concat(name_string, name.As<v8::String>());
1442+
}
1443+
}
1444+
name_string = v8::String::Concat(name_string,
1445+
FIXED_ONE_BYTE_STRING(isolate, " ["));
1446+
name_string = v8::String::Concat(name_string, code_value.As<v8::String>());
1447+
name_string = v8::String::Concat(name_string,
1448+
FIXED_ONE_BYTE_STRING(isolate, "]"));
1449+
1450+
set_maybe = err_object->Set(context, name_key, name_string);
1451+
RETURN_STATUS_IF_FALSE(env,
1452+
set_maybe.FromMaybe(false),
1453+
napi_generic_failure);
1454+
}
1455+
return napi_ok;
1456+
}
1457+
14011458
napi_status napi_create_error(napi_env env,
1459+
napi_value code,
14021460
napi_value msg,
14031461
napi_value* result) {
14041462
NAPI_PREAMBLE(env);
@@ -1408,13 +1466,18 @@ napi_status napi_create_error(napi_env env,
14081466
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue(msg);
14091467
RETURN_STATUS_IF_FALSE(env, message_value->IsString(), napi_string_expected);
14101468

1411-
*result = v8impl::JsValueFromV8LocalValue(v8::Exception::Error(
1412-
message_value.As<v8::String>()));
1469+
v8::Local<v8::Value> error_obj =
1470+
v8::Exception::Error(message_value.As<v8::String>());
1471+
napi_status status = set_error_code(env, error_obj, code, nullptr);
1472+
if (status != napi_ok) return status;
1473+
1474+
*result = v8impl::JsValueFromV8LocalValue(error_obj);
14131475

14141476
return GET_RETURN_STATUS(env);
14151477
}
14161478

14171479
napi_status napi_create_type_error(napi_env env,
1480+
napi_value code,
14181481
napi_value msg,
14191482
napi_value* result) {
14201483
NAPI_PREAMBLE(env);
@@ -1424,13 +1487,18 @@ napi_status napi_create_type_error(napi_env env,
14241487
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue(msg);
14251488
RETURN_STATUS_IF_FALSE(env, message_value->IsString(), napi_string_expected);
14261489

1427-
*result = v8impl::JsValueFromV8LocalValue(v8::Exception::TypeError(
1428-
message_value.As<v8::String>()));
1490+
v8::Local<v8::Value> error_obj =
1491+
v8::Exception::TypeError(message_value.As<v8::String>());
1492+
napi_status status = set_error_code(env, error_obj, code, nullptr);
1493+
if (status != napi_ok) return status;
1494+
1495+
*result = v8impl::JsValueFromV8LocalValue(error_obj);
14291496

14301497
return GET_RETURN_STATUS(env);
14311498
}
14321499

14331500
napi_status napi_create_range_error(napi_env env,
1501+
napi_value code,
14341502
napi_value msg,
14351503
napi_value* result) {
14361504
NAPI_PREAMBLE(env);
@@ -1440,8 +1508,12 @@ napi_status napi_create_range_error(napi_env env,
14401508
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue(msg);
14411509
RETURN_STATUS_IF_FALSE(env, message_value->IsString(), napi_string_expected);
14421510

1443-
*result = v8impl::JsValueFromV8LocalValue(v8::Exception::RangeError(
1444-
message_value.As<v8::String>()));
1511+
v8::Local<v8::Value> error_obj =
1512+
v8::Exception::RangeError(message_value.As<v8::String>());
1513+
napi_status status = set_error_code(env, error_obj, code, nullptr);
1514+
if (status != napi_ok) return status;
1515+
1516+
*result = v8impl::JsValueFromV8LocalValue(error_obj);
14451517

14461518
return GET_RETURN_STATUS(env);
14471519
}
@@ -1614,40 +1686,58 @@ napi_status napi_throw(napi_env env, napi_value error) {
16141686
return napi_clear_last_error(env);
16151687
}
16161688

1617-
napi_status napi_throw_error(napi_env env, const char* msg) {
1689+
napi_status napi_throw_error(napi_env env,
1690+
const char* code,
1691+
const char* msg) {
16181692
NAPI_PREAMBLE(env);
16191693

16201694
v8::Isolate* isolate = env->isolate;
16211695
v8::Local<v8::String> str;
16221696
CHECK_NEW_FROM_UTF8(env, str, msg);
16231697

1624-
isolate->ThrowException(v8::Exception::Error(str));
1698+
v8::Local<v8::Value> error_obj = v8::Exception::Error(str);
1699+
napi_status status = set_error_code(env, error_obj, nullptr, code);
1700+
if (status != napi_ok) return status;
1701+
1702+
isolate->ThrowException(error_obj);
16251703
// any VM calls after this point and before returning
16261704
// to the javascript invoker will fail
16271705
return napi_clear_last_error(env);
16281706
}
16291707

1630-
napi_status napi_throw_type_error(napi_env env, const char* msg) {
1708+
napi_status napi_throw_type_error(napi_env env,
1709+
const char* code,
1710+
const char* msg) {
16311711
NAPI_PREAMBLE(env);
16321712

16331713
v8::Isolate* isolate = env->isolate;
16341714
v8::Local<v8::String> str;
16351715
CHECK_NEW_FROM_UTF8(env, str, msg);
16361716

1637-
isolate->ThrowException(v8::Exception::TypeError(str));
1717+
v8::Local<v8::Value> error_obj = v8::Exception::TypeError(str);
1718+
napi_status status = set_error_code(env, error_obj, nullptr, code);
1719+
if (status != napi_ok) return status;
1720+
1721+
isolate->ThrowException(error_obj);
16381722
// any VM calls after this point and before returning
16391723
// to the javascript invoker will fail
16401724
return napi_clear_last_error(env);
16411725
}
16421726

1643-
napi_status napi_throw_range_error(napi_env env, const char* msg) {
1727+
napi_status napi_throw_range_error(napi_env env,
1728+
const char* code,
1729+
const char* msg) {
16441730
NAPI_PREAMBLE(env);
16451731

16461732
v8::Isolate* isolate = env->isolate;
16471733
v8::Local<v8::String> str;
16481734
CHECK_NEW_FROM_UTF8(env, str, msg);
16491735

1650-
isolate->ThrowException(v8::Exception::RangeError(str));
1736+
v8::Local<v8::Value> error_obj = v8::Exception::RangeError(str);
1737+
napi_status status = set_error_code(env, error_obj, nullptr, code);
1738+
if (status != napi_ok) return status;
1739+
1740+
isolate->ThrowException(error_obj);
16511741
// any VM calls after this point and before returning
16521742
// to the javascript invoker will fail
16531743
return napi_clear_last_error(env);
@@ -2244,7 +2334,9 @@ napi_status napi_instanceof(napi_env env,
22442334
CHECK_TO_OBJECT(env, context, ctor, constructor);
22452335

22462336
if (!ctor->IsFunction()) {
2247-
napi_throw_type_error(env, "constructor must be a function");
2337+
napi_throw_type_error(env,
2338+
"ERR_NAPI_CONS_FUNCTION",
2339+
"Constructor must be a function");
22482340

22492341
return napi_set_last_error(env, napi_function_expected);
22502342
}
@@ -2312,7 +2404,10 @@ napi_status napi_instanceof(napi_env env,
23122404

23132405
v8::Local<v8::Value> prototype_property = maybe_prototype.ToLocalChecked();
23142406
if (!prototype_property->IsObject()) {
2315-
napi_throw_type_error(env, "constructor.prototype must be an object");
2407+
napi_throw_type_error(
2408+
env,
2409+
"ERR_NAPI_CONS_PROTOTYPE_OBJECT",
2410+
"Constructor.prototype must be an object");
23162411

23172412
return napi_set_last_error(env, napi_object_expected);
23182413
}

src/node_api.h

+12-3
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,15 @@ NAPI_EXTERN napi_status napi_create_function(napi_env env,
142142
void* data,
143143
napi_value* result);
144144
NAPI_EXTERN napi_status napi_create_error(napi_env env,
145+
napi_value code,
145146
napi_value msg,
146147
napi_value* result);
147148
NAPI_EXTERN napi_status napi_create_type_error(napi_env env,
149+
napi_value code,
148150
napi_value msg,
149151
napi_value* result);
150152
NAPI_EXTERN napi_status napi_create_range_error(napi_env env,
153+
napi_value code,
151154
napi_value msg,
152155
napi_value* result);
153156

@@ -392,9 +395,15 @@ NAPI_EXTERN napi_status napi_escape_handle(napi_env env,
392395

393396
// Methods to support error handling
394397
NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error);
395-
NAPI_EXTERN napi_status napi_throw_error(napi_env env, const char* msg);
396-
NAPI_EXTERN napi_status napi_throw_type_error(napi_env env, const char* msg);
397-
NAPI_EXTERN napi_status napi_throw_range_error(napi_env env, const char* msg);
398+
NAPI_EXTERN napi_status napi_throw_error(napi_env env,
399+
const char* code,
400+
const char* msg);
401+
NAPI_EXTERN napi_status napi_throw_type_error(napi_env env,
402+
const char* code,
403+
const char* msg);
404+
NAPI_EXTERN napi_status napi_throw_range_error(napi_env env,
405+
const char* code,
406+
const char* msg);
398407
NAPI_EXTERN napi_status napi_is_error(napi_env env,
399408
napi_value value,
400409
bool* result);

0 commit comments

Comments
 (0)