@@ -1523,7 +1523,61 @@ napi_status napi_create_symbol(napi_env env,
15231523 return GET_RETURN_STATUS (env);
15241524}
15251525
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+
15261579napi_status napi_create_error (napi_env env,
1580+ napi_value code,
15271581 napi_value msg,
15281582 napi_value* result) {
15291583 NAPI_PREAMBLE (env);
@@ -1533,13 +1587,18 @@ napi_status napi_create_error(napi_env env,
15331587 v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
15341588 RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
15351589
1536- *result = v8impl::JsValueFromV8LocalValue (v8::Exception::Error (
1537- 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);
15381596
15391597 return GET_RETURN_STATUS (env);
15401598}
15411599
15421600napi_status napi_create_type_error (napi_env env,
1601+ napi_value code,
15431602 napi_value msg,
15441603 napi_value* result) {
15451604 NAPI_PREAMBLE (env);
@@ -1549,13 +1608,18 @@ napi_status napi_create_type_error(napi_env env,
15491608 v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
15501609 RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
15511610
1552- *result = v8impl::JsValueFromV8LocalValue (v8::Exception::TypeError (
1553- 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);
15541617
15551618 return GET_RETURN_STATUS (env);
15561619}
15571620
15581621napi_status napi_create_range_error (napi_env env,
1622+ napi_value code,
15591623 napi_value msg,
15601624 napi_value* result) {
15611625 NAPI_PREAMBLE (env);
@@ -1565,8 +1629,12 @@ napi_status napi_create_range_error(napi_env env,
15651629 v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
15661630 RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
15671631
1568- *result = v8impl::JsValueFromV8LocalValue (v8::Exception::RangeError (
1569- 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);
15701638
15711639 return GET_RETURN_STATUS (env);
15721640}
@@ -1739,40 +1807,58 @@ napi_status napi_throw(napi_env env, napi_value error) {
17391807 return napi_clear_last_error (env);
17401808}
17411809
1742- 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) {
17431813 NAPI_PREAMBLE (env);
17441814
17451815 v8::Isolate* isolate = env->isolate ;
17461816 v8::Local<v8::String> str;
17471817 CHECK_NEW_FROM_UTF8 (env, str, msg);
17481818
1749- 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);
17501824 // any VM calls after this point and before returning
17511825 // to the javascript invoker will fail
17521826 return napi_clear_last_error (env);
17531827}
17541828
1755- 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) {
17561832 NAPI_PREAMBLE (env);
17571833
17581834 v8::Isolate* isolate = env->isolate ;
17591835 v8::Local<v8::String> str;
17601836 CHECK_NEW_FROM_UTF8 (env, str, msg);
17611837
1762- 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);
17631843 // any VM calls after this point and before returning
17641844 // to the javascript invoker will fail
17651845 return napi_clear_last_error (env);
17661846}
17671847
1768- 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) {
17691851 NAPI_PREAMBLE (env);
17701852
17711853 v8::Isolate* isolate = env->isolate ;
17721854 v8::Local<v8::String> str;
17731855 CHECK_NEW_FROM_UTF8 (env, str, msg);
17741856
1775- 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);
17761862 // any VM calls after this point and before returning
17771863 // to the javascript invoker will fail
17781864 return napi_clear_last_error (env);
@@ -2392,7 +2478,9 @@ napi_status napi_instanceof(napi_env env,
23922478 CHECK_TO_OBJECT (env, context, ctor, constructor);
23932479
23942480 if (!ctor->IsFunction ()) {
2395- 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" );
23962484
23972485 return napi_set_last_error (env, napi_function_expected);
23982486 }
@@ -2460,7 +2548,10 @@ napi_status napi_instanceof(napi_env env,
24602548
24612549 v8::Local<v8::Value> prototype_property = maybe_prototype.ToLocalChecked ();
24622550 if (!prototype_property->IsObject ()) {
2463- 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" );
24642555
24652556 return napi_set_last_error (env, napi_object_expected);
24662557 }
0 commit comments