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