@@ -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