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
@@ -1527,7 +1528,61 @@ napi_status napi_create_symbol(napi_env env,
1527
1528
return GET_RETURN_STATUS (env);
1528
1529
}
1529
1530
1531
+ static napi_status set_error_code (napi_env env,
1532
+ v8::Local<v8::Value> error,
1533
+ napi_value code,
1534
+ const char * code_cstring) {
1535
+ if ((code != nullptr ) || (code_cstring != nullptr )) {
1536
+ v8::Isolate* isolate = env->isolate ;
1537
+ v8::Local<v8::Context> context = isolate->GetCurrentContext ();
1538
+ v8::Local<v8::Object> err_object = error.As <v8::Object>();
1539
+
1540
+ v8::Local<v8::Value> code_value = v8impl::V8LocalValueFromJsValue (code);
1541
+ if (code != nullptr ) {
1542
+ code_value = v8impl::V8LocalValueFromJsValue (code);
1543
+ RETURN_STATUS_IF_FALSE (env, code_value->IsString (), napi_string_expected);
1544
+ } else {
1545
+ CHECK_NEW_FROM_UTF8 (env, code_value, code_cstring);
1546
+ }
1547
+
1548
+ v8::Local<v8::Name> code_key;
1549
+ CHECK_NEW_FROM_UTF8 (env, code_key, " code" );
1550
+
1551
+ v8::Maybe<bool > set_maybe = err_object->Set (context, code_key, code_value);
1552
+ RETURN_STATUS_IF_FALSE (env,
1553
+ set_maybe.FromMaybe (false ),
1554
+ napi_generic_failure);
1555
+
1556
+ // now update the name to be "name [code]" where name is the
1557
+ // original name and code is the code associated with the Error
1558
+ v8::Local<v8::String> name_string;
1559
+ CHECK_NEW_FROM_UTF8 (env, name_string, " " );
1560
+ v8::Local<v8::Name> name_key;
1561
+ CHECK_NEW_FROM_UTF8 (env, name_key, " name" );
1562
+
1563
+ auto maybe_name = err_object->Get (context, name_key);
1564
+ if (!maybe_name.IsEmpty ()) {
1565
+ v8::Local<v8::Value> name = maybe_name.ToLocalChecked ();
1566
+ if (name->IsString ()) {
1567
+ name_string = v8::String::Concat (name_string, name.As <v8::String>());
1568
+ }
1569
+ }
1570
+ name_string = v8::String::Concat (name_string,
1571
+ FIXED_ONE_BYTE_STRING (isolate, " [" ));
1572
+ name_string = v8::String::Concat (name_string, code_value.As <v8::String>());
1573
+ name_string = v8::String::Concat (name_string,
1574
+ FIXED_ONE_BYTE_STRING (isolate, " ]" ));
1575
+
1576
+ set_maybe = err_object->Set (context, name_key, name_string);
1577
+ RETURN_STATUS_IF_FALSE (env,
1578
+ set_maybe.FromMaybe (false ),
1579
+ napi_generic_failure);
1580
+ }
1581
+ return napi_ok;
1582
+ }
1583
+
1530
1584
napi_status napi_create_error (napi_env env,
1585
+ napi_value code,
1531
1586
napi_value msg,
1532
1587
napi_value* result) {
1533
1588
NAPI_PREAMBLE (env);
@@ -1537,13 +1592,18 @@ napi_status napi_create_error(napi_env env,
1537
1592
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
1538
1593
RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
1539
1594
1540
- *result = v8impl::JsValueFromV8LocalValue (v8::Exception::Error (
1541
- message_value.As <v8::String>()));
1595
+ v8::Local<v8::Value> error_obj =
1596
+ v8::Exception::Error (message_value.As <v8::String>());
1597
+ napi_status status = set_error_code (env, error_obj, code, nullptr );
1598
+ if (status != napi_ok) return status;
1599
+
1600
+ *result = v8impl::JsValueFromV8LocalValue (error_obj);
1542
1601
1543
1602
return GET_RETURN_STATUS (env);
1544
1603
}
1545
1604
1546
1605
napi_status napi_create_type_error (napi_env env,
1606
+ napi_value code,
1547
1607
napi_value msg,
1548
1608
napi_value* result) {
1549
1609
NAPI_PREAMBLE (env);
@@ -1553,13 +1613,18 @@ napi_status napi_create_type_error(napi_env env,
1553
1613
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
1554
1614
RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
1555
1615
1556
- *result = v8impl::JsValueFromV8LocalValue (v8::Exception::TypeError (
1557
- message_value.As <v8::String>()));
1616
+ v8::Local<v8::Value> error_obj =
1617
+ v8::Exception::TypeError (message_value.As <v8::String>());
1618
+ napi_status status = set_error_code (env, error_obj, code, nullptr );
1619
+ if (status != napi_ok) return status;
1620
+
1621
+ *result = v8impl::JsValueFromV8LocalValue (error_obj);
1558
1622
1559
1623
return GET_RETURN_STATUS (env);
1560
1624
}
1561
1625
1562
1626
napi_status napi_create_range_error (napi_env env,
1627
+ napi_value code,
1563
1628
napi_value msg,
1564
1629
napi_value* result) {
1565
1630
NAPI_PREAMBLE (env);
@@ -1569,8 +1634,12 @@ napi_status napi_create_range_error(napi_env env,
1569
1634
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
1570
1635
RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
1571
1636
1572
- *result = v8impl::JsValueFromV8LocalValue (v8::Exception::RangeError (
1573
- message_value.As <v8::String>()));
1637
+ v8::Local<v8::Value> error_obj =
1638
+ v8::Exception::RangeError (message_value.As <v8::String>());
1639
+ napi_status status = set_error_code (env, error_obj, code, nullptr );
1640
+ if (status != napi_ok) return status;
1641
+
1642
+ *result = v8impl::JsValueFromV8LocalValue (error_obj);
1574
1643
1575
1644
return GET_RETURN_STATUS (env);
1576
1645
}
@@ -1743,40 +1812,58 @@ napi_status napi_throw(napi_env env, napi_value error) {
1743
1812
return napi_clear_last_error (env);
1744
1813
}
1745
1814
1746
- napi_status napi_throw_error (napi_env env, const char * msg) {
1815
+ napi_status napi_throw_error (napi_env env,
1816
+ const char * code,
1817
+ const char * msg) {
1747
1818
NAPI_PREAMBLE (env);
1748
1819
1749
1820
v8::Isolate* isolate = env->isolate ;
1750
1821
v8::Local<v8::String> str;
1751
1822
CHECK_NEW_FROM_UTF8 (env, str, msg);
1752
1823
1753
- isolate->ThrowException (v8::Exception::Error (str));
1824
+ v8::Local<v8::Value> error_obj = v8::Exception::Error (str);
1825
+ napi_status status = set_error_code (env, error_obj, nullptr , code);
1826
+ if (status != napi_ok) return status;
1827
+
1828
+ isolate->ThrowException (error_obj);
1754
1829
// any VM calls after this point and before returning
1755
1830
// to the javascript invoker will fail
1756
1831
return napi_clear_last_error (env);
1757
1832
}
1758
1833
1759
- napi_status napi_throw_type_error (napi_env env, const char * msg) {
1834
+ napi_status napi_throw_type_error (napi_env env,
1835
+ const char * code,
1836
+ const char * msg) {
1760
1837
NAPI_PREAMBLE (env);
1761
1838
1762
1839
v8::Isolate* isolate = env->isolate ;
1763
1840
v8::Local<v8::String> str;
1764
1841
CHECK_NEW_FROM_UTF8 (env, str, msg);
1765
1842
1766
- isolate->ThrowException (v8::Exception::TypeError (str));
1843
+ v8::Local<v8::Value> error_obj = v8::Exception::TypeError (str);
1844
+ napi_status status = set_error_code (env, error_obj, nullptr , code);
1845
+ if (status != napi_ok) return status;
1846
+
1847
+ isolate->ThrowException (error_obj);
1767
1848
// any VM calls after this point and before returning
1768
1849
// to the javascript invoker will fail
1769
1850
return napi_clear_last_error (env);
1770
1851
}
1771
1852
1772
- napi_status napi_throw_range_error (napi_env env, const char * msg) {
1853
+ napi_status napi_throw_range_error (napi_env env,
1854
+ const char * code,
1855
+ const char * msg) {
1773
1856
NAPI_PREAMBLE (env);
1774
1857
1775
1858
v8::Isolate* isolate = env->isolate ;
1776
1859
v8::Local<v8::String> str;
1777
1860
CHECK_NEW_FROM_UTF8 (env, str, msg);
1778
1861
1779
- isolate->ThrowException (v8::Exception::RangeError (str));
1862
+ v8::Local<v8::Value> error_obj = v8::Exception::RangeError (str);
1863
+ napi_status status = set_error_code (env, error_obj, nullptr , code);
1864
+ if (status != napi_ok) return status;
1865
+
1866
+ isolate->ThrowException (error_obj);
1780
1867
// any VM calls after this point and before returning
1781
1868
// to the javascript invoker will fail
1782
1869
return napi_clear_last_error (env);
@@ -2415,7 +2502,9 @@ napi_status napi_instanceof(napi_env env,
2415
2502
CHECK_TO_OBJECT (env, context, ctor, constructor);
2416
2503
2417
2504
if (!ctor->IsFunction ()) {
2418
- napi_throw_type_error (env, " constructor must be a function" );
2505
+ napi_throw_type_error (env,
2506
+ " ERR_NAPI_CONS_FUNCTION" ,
2507
+ " Constructor must be a function" );
2419
2508
2420
2509
return napi_set_last_error (env, napi_function_expected);
2421
2510
}
@@ -2483,7 +2572,10 @@ napi_status napi_instanceof(napi_env env,
2483
2572
2484
2573
v8::Local<v8::Value> prototype_property = maybe_prototype.ToLocalChecked ();
2485
2574
if (!prototype_property->IsObject ()) {
2486
- napi_throw_type_error (env, " constructor.prototype must be an object" );
2575
+ napi_throw_type_error (
2576
+ env,
2577
+ " ERR_NAPI_CONS_PROTOTYPE_OBJECT" ,
2578
+ " Constructor.prototype must be an object" );
2487
2579
2488
2580
return napi_set_last_error (env, napi_object_expected);
2489
2581
}
0 commit comments