18
18
#include " uv.h"
19
19
#include " node_api.h"
20
20
#include " node_internals.h"
21
+ #include " util.h"
21
22
22
23
#define NAPI_VERSION 1
23
24
@@ -1522,7 +1523,61 @@ napi_status napi_create_symbol(napi_env env,
1522
1523
return GET_RETURN_STATUS (env);
1523
1524
}
1524
1525
1526
+ static napi_status set_error_code (napi_env env,
1527
+ v8::Local<v8::Value> error,
1528
+ napi_value code,
1529
+ const char * code_cstring) {
1530
+ if ((code != nullptr ) || (code_cstring != nullptr )) {
1531
+ v8::Isolate* isolate = env->isolate ;
1532
+ v8::Local<v8::Context> context = isolate->GetCurrentContext ();
1533
+ v8::Local<v8::Object> err_object = error.As <v8::Object>();
1534
+
1535
+ v8::Local<v8::Value> code_value = v8impl::V8LocalValueFromJsValue (code);
1536
+ if (code != nullptr ) {
1537
+ code_value = v8impl::V8LocalValueFromJsValue (code);
1538
+ RETURN_STATUS_IF_FALSE (env, code_value->IsString (), napi_string_expected);
1539
+ } else {
1540
+ CHECK_NEW_FROM_UTF8 (env, code_value, code_cstring);
1541
+ }
1542
+
1543
+ v8::Local<v8::Name> code_key;
1544
+ CHECK_NEW_FROM_UTF8 (env, code_key, " code" );
1545
+
1546
+ v8::Maybe<bool > set_maybe = err_object->Set (context, code_key, code_value);
1547
+ RETURN_STATUS_IF_FALSE (env,
1548
+ set_maybe.FromMaybe (false ),
1549
+ napi_generic_failure);
1550
+
1551
+ // now update the name to be "name [code]" where name is the
1552
+ // original name and code is the code associated with the Error
1553
+ v8::Local<v8::String> name_string;
1554
+ CHECK_NEW_FROM_UTF8 (env, name_string, " " );
1555
+ v8::Local<v8::Name> name_key;
1556
+ CHECK_NEW_FROM_UTF8 (env, name_key, " name" );
1557
+
1558
+ auto maybe_name = err_object->Get (context, name_key);
1559
+ if (!maybe_name.IsEmpty ()) {
1560
+ v8::Local<v8::Value> name = maybe_name.ToLocalChecked ();
1561
+ if (name->IsString ()) {
1562
+ name_string = v8::String::Concat (name_string, name.As <v8::String>());
1563
+ }
1564
+ }
1565
+ name_string = v8::String::Concat (name_string,
1566
+ FIXED_ONE_BYTE_STRING (isolate, " [" ));
1567
+ name_string = v8::String::Concat (name_string, code_value.As <v8::String>());
1568
+ name_string = v8::String::Concat (name_string,
1569
+ FIXED_ONE_BYTE_STRING (isolate, " ]" ));
1570
+
1571
+ set_maybe = err_object->Set (context, name_key, name_string);
1572
+ RETURN_STATUS_IF_FALSE (env,
1573
+ set_maybe.FromMaybe (false ),
1574
+ napi_generic_failure);
1575
+ }
1576
+ return napi_ok;
1577
+ }
1578
+
1525
1579
napi_status napi_create_error (napi_env env,
1580
+ napi_value code,
1526
1581
napi_value msg,
1527
1582
napi_value* result) {
1528
1583
NAPI_PREAMBLE (env);
@@ -1532,13 +1587,18 @@ napi_status napi_create_error(napi_env env,
1532
1587
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
1533
1588
RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
1534
1589
1535
- *result = v8impl::JsValueFromV8LocalValue (v8::Exception::Error (
1536
- message_value.As <v8::String>()));
1590
+ v8::Local<v8::Value> error_obj =
1591
+ v8::Exception::Error (message_value.As <v8::String>());
1592
+ napi_status status = set_error_code (env, error_obj, code, nullptr );
1593
+ if (status != napi_ok) return status;
1594
+
1595
+ *result = v8impl::JsValueFromV8LocalValue (error_obj);
1537
1596
1538
1597
return GET_RETURN_STATUS (env);
1539
1598
}
1540
1599
1541
1600
napi_status napi_create_type_error (napi_env env,
1601
+ napi_value code,
1542
1602
napi_value msg,
1543
1603
napi_value* result) {
1544
1604
NAPI_PREAMBLE (env);
@@ -1548,13 +1608,18 @@ napi_status napi_create_type_error(napi_env env,
1548
1608
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
1549
1609
RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
1550
1610
1551
- *result = v8impl::JsValueFromV8LocalValue (v8::Exception::TypeError (
1552
- message_value.As <v8::String>()));
1611
+ v8::Local<v8::Value> error_obj =
1612
+ v8::Exception::TypeError (message_value.As <v8::String>());
1613
+ napi_status status = set_error_code (env, error_obj, code, nullptr );
1614
+ if (status != napi_ok) return status;
1615
+
1616
+ *result = v8impl::JsValueFromV8LocalValue (error_obj);
1553
1617
1554
1618
return GET_RETURN_STATUS (env);
1555
1619
}
1556
1620
1557
1621
napi_status napi_create_range_error (napi_env env,
1622
+ napi_value code,
1558
1623
napi_value msg,
1559
1624
napi_value* result) {
1560
1625
NAPI_PREAMBLE (env);
@@ -1564,8 +1629,12 @@ napi_status napi_create_range_error(napi_env env,
1564
1629
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
1565
1630
RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
1566
1631
1567
- *result = v8impl::JsValueFromV8LocalValue (v8::Exception::RangeError (
1568
- message_value.As <v8::String>()));
1632
+ v8::Local<v8::Value> error_obj =
1633
+ v8::Exception::RangeError (message_value.As <v8::String>());
1634
+ napi_status status = set_error_code (env, error_obj, code, nullptr );
1635
+ if (status != napi_ok) return status;
1636
+
1637
+ *result = v8impl::JsValueFromV8LocalValue (error_obj);
1569
1638
1570
1639
return GET_RETURN_STATUS (env);
1571
1640
}
@@ -1738,40 +1807,58 @@ napi_status napi_throw(napi_env env, napi_value error) {
1738
1807
return napi_clear_last_error (env);
1739
1808
}
1740
1809
1741
- napi_status napi_throw_error (napi_env env, const char * msg) {
1810
+ napi_status napi_throw_error (napi_env env,
1811
+ const char * code,
1812
+ const char * msg) {
1742
1813
NAPI_PREAMBLE (env);
1743
1814
1744
1815
v8::Isolate* isolate = env->isolate ;
1745
1816
v8::Local<v8::String> str;
1746
1817
CHECK_NEW_FROM_UTF8 (env, str, msg);
1747
1818
1748
- isolate->ThrowException (v8::Exception::Error (str));
1819
+ v8::Local<v8::Value> error_obj = v8::Exception::Error (str);
1820
+ napi_status status = set_error_code (env, error_obj, nullptr , code);
1821
+ if (status != napi_ok) return status;
1822
+
1823
+ isolate->ThrowException (error_obj);
1749
1824
// any VM calls after this point and before returning
1750
1825
// to the javascript invoker will fail
1751
1826
return napi_clear_last_error (env);
1752
1827
}
1753
1828
1754
- napi_status napi_throw_type_error (napi_env env, const char * msg) {
1829
+ napi_status napi_throw_type_error (napi_env env,
1830
+ const char * code,
1831
+ const char * msg) {
1755
1832
NAPI_PREAMBLE (env);
1756
1833
1757
1834
v8::Isolate* isolate = env->isolate ;
1758
1835
v8::Local<v8::String> str;
1759
1836
CHECK_NEW_FROM_UTF8 (env, str, msg);
1760
1837
1761
- isolate->ThrowException (v8::Exception::TypeError (str));
1838
+ v8::Local<v8::Value> error_obj = v8::Exception::TypeError (str);
1839
+ napi_status status = set_error_code (env, error_obj, nullptr , code);
1840
+ if (status != napi_ok) return status;
1841
+
1842
+ isolate->ThrowException (error_obj);
1762
1843
// any VM calls after this point and before returning
1763
1844
// to the javascript invoker will fail
1764
1845
return napi_clear_last_error (env);
1765
1846
}
1766
1847
1767
- napi_status napi_throw_range_error (napi_env env, const char * msg) {
1848
+ napi_status napi_throw_range_error (napi_env env,
1849
+ const char * code,
1850
+ const char * msg) {
1768
1851
NAPI_PREAMBLE (env);
1769
1852
1770
1853
v8::Isolate* isolate = env->isolate ;
1771
1854
v8::Local<v8::String> str;
1772
1855
CHECK_NEW_FROM_UTF8 (env, str, msg);
1773
1856
1774
- isolate->ThrowException (v8::Exception::RangeError (str));
1857
+ v8::Local<v8::Value> error_obj = v8::Exception::RangeError (str);
1858
+ napi_status status = set_error_code (env, error_obj, nullptr , code);
1859
+ if (status != napi_ok) return status;
1860
+
1861
+ isolate->ThrowException (error_obj);
1775
1862
// any VM calls after this point and before returning
1776
1863
// to the javascript invoker will fail
1777
1864
return napi_clear_last_error (env);
@@ -2391,7 +2478,9 @@ napi_status napi_instanceof(napi_env env,
2391
2478
CHECK_TO_OBJECT (env, context, ctor, constructor);
2392
2479
2393
2480
if (!ctor->IsFunction ()) {
2394
- napi_throw_type_error (env, " constructor must be a function" );
2481
+ napi_throw_type_error (env,
2482
+ " ERR_NAPI_CONS_FUNCTION" ,
2483
+ " Constructor must be a function" );
2395
2484
2396
2485
return napi_set_last_error (env, napi_function_expected);
2397
2486
}
@@ -2459,7 +2548,10 @@ napi_status napi_instanceof(napi_env env,
2459
2548
2460
2549
v8::Local<v8::Value> prototype_property = maybe_prototype.ToLocalChecked ();
2461
2550
if (!prototype_property->IsObject ()) {
2462
- napi_throw_type_error (env, " constructor.prototype must be an object" );
2551
+ napi_throw_type_error (
2552
+ env,
2553
+ " ERR_NAPI_CONS_PROTOTYPE_OBJECT" ,
2554
+ " Constructor.prototype must be an object" );
2463
2555
2464
2556
return napi_set_last_error (env, napi_object_expected);
2465
2557
}
0 commit comments