18
18
#include " uv.h"
19
19
#include " node_api.h"
20
20
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
+
21
25
static
22
26
napi_status napi_set_last_error (napi_env env, napi_status error_code,
23
27
uint32_t engine_error_code = 0 ,
@@ -1398,7 +1402,61 @@ napi_status napi_create_symbol(napi_env env,
1398
1402
return GET_RETURN_STATUS (env);
1399
1403
}
1400
1404
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
+
1401
1458
napi_status napi_create_error (napi_env env,
1459
+ napi_value code,
1402
1460
napi_value msg,
1403
1461
napi_value* result) {
1404
1462
NAPI_PREAMBLE (env);
@@ -1408,13 +1466,18 @@ napi_status napi_create_error(napi_env env,
1408
1466
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
1409
1467
RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
1410
1468
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);
1413
1475
1414
1476
return GET_RETURN_STATUS (env);
1415
1477
}
1416
1478
1417
1479
napi_status napi_create_type_error (napi_env env,
1480
+ napi_value code,
1418
1481
napi_value msg,
1419
1482
napi_value* result) {
1420
1483
NAPI_PREAMBLE (env);
@@ -1424,13 +1487,18 @@ napi_status napi_create_type_error(napi_env env,
1424
1487
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
1425
1488
RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
1426
1489
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);
1429
1496
1430
1497
return GET_RETURN_STATUS (env);
1431
1498
}
1432
1499
1433
1500
napi_status napi_create_range_error (napi_env env,
1501
+ napi_value code,
1434
1502
napi_value msg,
1435
1503
napi_value* result) {
1436
1504
NAPI_PREAMBLE (env);
@@ -1440,8 +1508,12 @@ napi_status napi_create_range_error(napi_env env,
1440
1508
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
1441
1509
RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
1442
1510
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);
1445
1517
1446
1518
return GET_RETURN_STATUS (env);
1447
1519
}
@@ -1614,40 +1686,58 @@ napi_status napi_throw(napi_env env, napi_value error) {
1614
1686
return napi_clear_last_error (env);
1615
1687
}
1616
1688
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) {
1618
1692
NAPI_PREAMBLE (env);
1619
1693
1620
1694
v8::Isolate* isolate = env->isolate ;
1621
1695
v8::Local<v8::String> str;
1622
1696
CHECK_NEW_FROM_UTF8 (env, str, msg);
1623
1697
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);
1625
1703
// any VM calls after this point and before returning
1626
1704
// to the javascript invoker will fail
1627
1705
return napi_clear_last_error (env);
1628
1706
}
1629
1707
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) {
1631
1711
NAPI_PREAMBLE (env);
1632
1712
1633
1713
v8::Isolate* isolate = env->isolate ;
1634
1714
v8::Local<v8::String> str;
1635
1715
CHECK_NEW_FROM_UTF8 (env, str, msg);
1636
1716
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);
1638
1722
// any VM calls after this point and before returning
1639
1723
// to the javascript invoker will fail
1640
1724
return napi_clear_last_error (env);
1641
1725
}
1642
1726
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) {
1644
1730
NAPI_PREAMBLE (env);
1645
1731
1646
1732
v8::Isolate* isolate = env->isolate ;
1647
1733
v8::Local<v8::String> str;
1648
1734
CHECK_NEW_FROM_UTF8 (env, str, msg);
1649
1735
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);
1651
1741
// any VM calls after this point and before returning
1652
1742
// to the javascript invoker will fail
1653
1743
return napi_clear_last_error (env);
@@ -2244,7 +2334,9 @@ napi_status napi_instanceof(napi_env env,
2244
2334
CHECK_TO_OBJECT (env, context, ctor, constructor);
2245
2335
2246
2336
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" );
2248
2340
2249
2341
return napi_set_last_error (env, napi_function_expected);
2250
2342
}
@@ -2312,7 +2404,10 @@ napi_status napi_instanceof(napi_env env,
2312
2404
2313
2405
v8::Local<v8::Value> prototype_property = maybe_prototype.ToLocalChecked ();
2314
2406
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" );
2316
2411
2317
2412
return napi_set_last_error (env, napi_object_expected);
2318
2413
}
0 commit comments