From f2efdc880f8edd2cd0d2e7268a77a6c56591e3cc Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Wed, 28 Jun 2017 21:53:18 -0400 Subject: [PATCH] n-api: add code parameter to error helpers In support of the effort to add error codes to all errors generated by Node.js, add an optional code parameter to the helper functions used to throw/create errors in N-API. Backport-PR-URL: https://github.com/nodejs/node/pull/14453 Backport-Reviewed-By: James M Snell PR-URL: https://github.com/nodejs/node/pull/13988 Fixes: https://github.com/nodejs/node/issues/13933 Reviewed-By: James M Snell Reviewed-By: Anna Henningsen --- doc/api/n-api.md | 49 ++++++- lib/internal/errors.js | 4 + src/node_api.cc | 120 ++++++++++++++++-- src/node_api.h | 15 ++- test/addons-napi/common.h | 3 +- test/addons-napi/test_async/test_async.cc | 6 +- test/addons-napi/test_error/test.js | 62 +++++++++ test/addons-napi/test_error/test_error.cc | 76 ++++++++++- .../test_typedarray/test_typedarray.c | 2 +- 9 files changed, 305 insertions(+), 32 deletions(-) diff --git a/doc/api/n-api.md b/doc/api/n-api.md index 1a6c9e143ed61c..924e39e9b75f73 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -323,6 +323,31 @@ code needs to create an Error object: [`napi_create_error`][], where result is the napi_value that refers to the newly created JavaScript Error object. +The Node.js project is adding error codes to all of the errors +generated internally. The goal is for applications to use these +error codes for all error checking. The associated error messages +will remain, but will only be meant to be used for logging and +display with the expectation that the message can change without +SemVer applying. In order to support this model with N-API, both +in internal functionality and for module specific functionality +(as its good practice), the `throw_` and `create_` functions +take an optional code parameter which is the string for the code +to be added to the error object. If the optional parameter is NULL +then no code will be associated with the error. If a code is provided, +the name associated with the error is also updated to be: + +``` +originalName [code] +``` + +where originalName is the original name associated with the error +and code is the code that was provided. For example if the code +is 'ERR_ERROR_1' and a TypeError is being created the name will be: + +``` +TypeError [ERR_ERROR_1] +``` + #### napi_throw ```C -NODE_EXTERN napi_status napi_throw_error(napi_env env, const char* msg); +NODE_EXTERN napi_status napi_throw_error(napi_env env, + const char* code, + const char* msg); ``` - `[in] env`: The environment that the API is invoked under. +- `[in] code`: Optional error code to be set on the error. - `[in] msg`: C string representing the text to be associated with the error. @@ -358,9 +386,12 @@ This API throws a JavaScript Error with the text provided. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_throw_type_error(napi_env env, const char* msg); +NODE_EXTERN napi_status napi_throw_type_error(napi_env env, + const char* code, + const char* msg); ``` - `[in] env`: The environment that the API is invoked under. +- `[in] code`: Optional error code to be set on the error. - `[in] msg`: C string representing the text to be associated with the error. @@ -373,9 +404,12 @@ This API throws a JavaScript TypeError with the text provided. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_throw_range_error(napi_env env, const char* msg); +NODE_EXTERN napi_status napi_throw_range_error(napi_env env, + const char* code, + const char* msg); ``` - `[in] env`: The environment that the API is invoked under. +- `[in] code`: Optional error code to be set on the error. - `[in] msg`: C string representing the text to be associated with the error. @@ -409,10 +443,13 @@ added: v8.0.0 --> ```C NODE_EXTERN napi_status napi_create_error(napi_env env, + napi_value code, napi_value msg, napi_value* result); ``` - `[in] env`: The environment that the API is invoked under. +- `[in] code`: Optional `napi_value` with the string for the error code to + be associated with the error. - `[in] msg`: napi_value that references a JavaScript String to be used as the message for the Error. - `[out] result`: `napi_value` representing the error created. @@ -427,10 +464,13 @@ added: v8.0.0 --> ```C NODE_EXTERN napi_status napi_create_type_error(napi_env env, + napi_value code, napi_value msg, napi_value* result); ``` - `[in] env`: The environment that the API is invoked under. +- `[in] code`: Optional `napi_value` with the string for the error code to + be associated with the error. - `[in] msg`: napi_value that references a JavaScript String to be used as the message for the Error. - `[out] result`: `napi_value` representing the error created. @@ -446,10 +486,13 @@ added: v8.0.0 --> ```C NODE_EXTERN napi_status napi_create_range_error(napi_env env, + napi_value code, const char* msg, napi_value* result); ``` - `[in] env`: The environment that the API is invoked under. +- `[in] code`: Optional `napi_value` with the string for the error code to + be associated with the error. - `[in] msg`: napi_value that references a JavaScript String to be used as the message for the Error. - `[out] result`: `napi_value` representing the error created. diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 402377a3a17287..7725f4560dc885 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -143,6 +143,10 @@ E('ERR_UNKNOWN_BUILTIN_MODULE', (id) => `No such built-in module: ${id}`); E('ERR_UNKNOWN_SIGNAL', (signal) => `Unknown signal: ${signal}`); E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type'); E('ERR_UNKNOWN_STREAM_TYPE', 'Unknown stream file type'); +E('ERR_NAPI_CONS_FUNCTION', 'Constructor must be a function'); +E('ERR_NAPI_CONS_PROTOTYPE_OBJECT', 'Constructor.prototype must be an object'); +E('ERR_NO_CRYPTO', 'Node.js is not compiled with OpenSSL crypto support'); +E('ERR_PARSE_HISTORY_DATA', 'Could not parse history data in %s'); E('ERR_SOCKET_ALREADY_BOUND', 'Socket is already bound'); E('ERR_SOCKET_BAD_TYPE', 'Bad socket type specified. Valid types are: udp4, udp6'); diff --git a/src/node_api.cc b/src/node_api.cc index d7df50e2b5729f..5818cb25c1b6e8 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -18,6 +18,7 @@ #include "uv.h" #include "node_api.h" #include "node_internals.h" +#include "util.h" #define NAPI_VERSION 1 @@ -1527,7 +1528,61 @@ napi_status napi_create_symbol(napi_env env, return GET_RETURN_STATUS(env); } +static napi_status set_error_code(napi_env env, + v8::Local error, + napi_value code, + const char* code_cstring) { + if ((code != nullptr) || (code_cstring != nullptr)) { + v8::Isolate* isolate = env->isolate; + v8::Local context = isolate->GetCurrentContext(); + v8::Local err_object = error.As(); + + v8::Local code_value = v8impl::V8LocalValueFromJsValue(code); + if (code != nullptr) { + code_value = v8impl::V8LocalValueFromJsValue(code); + RETURN_STATUS_IF_FALSE(env, code_value->IsString(), napi_string_expected); + } else { + CHECK_NEW_FROM_UTF8(env, code_value, code_cstring); + } + + v8::Local code_key; + CHECK_NEW_FROM_UTF8(env, code_key, "code"); + + v8::Maybe set_maybe = err_object->Set(context, code_key, code_value); + RETURN_STATUS_IF_FALSE(env, + set_maybe.FromMaybe(false), + napi_generic_failure); + + // now update the name to be "name [code]" where name is the + // original name and code is the code associated with the Error + v8::Local name_string; + CHECK_NEW_FROM_UTF8(env, name_string, ""); + v8::Local name_key; + CHECK_NEW_FROM_UTF8(env, name_key, "name"); + + auto maybe_name = err_object->Get(context, name_key); + if (!maybe_name.IsEmpty()) { + v8::Local name = maybe_name.ToLocalChecked(); + if (name->IsString()) { + name_string = v8::String::Concat(name_string, name.As()); + } + } + name_string = v8::String::Concat(name_string, + FIXED_ONE_BYTE_STRING(isolate, " [")); + name_string = v8::String::Concat(name_string, code_value.As()); + name_string = v8::String::Concat(name_string, + FIXED_ONE_BYTE_STRING(isolate, "]")); + + set_maybe = err_object->Set(context, name_key, name_string); + RETURN_STATUS_IF_FALSE(env, + set_maybe.FromMaybe(false), + napi_generic_failure); + } + return napi_ok; +} + napi_status napi_create_error(napi_env env, + napi_value code, napi_value msg, napi_value* result) { NAPI_PREAMBLE(env); @@ -1537,13 +1592,18 @@ napi_status napi_create_error(napi_env env, v8::Local message_value = v8impl::V8LocalValueFromJsValue(msg); RETURN_STATUS_IF_FALSE(env, message_value->IsString(), napi_string_expected); - *result = v8impl::JsValueFromV8LocalValue(v8::Exception::Error( - message_value.As())); + v8::Local error_obj = + v8::Exception::Error(message_value.As()); + napi_status status = set_error_code(env, error_obj, code, nullptr); + if (status != napi_ok) return status; + + *result = v8impl::JsValueFromV8LocalValue(error_obj); return GET_RETURN_STATUS(env); } napi_status napi_create_type_error(napi_env env, + napi_value code, napi_value msg, napi_value* result) { NAPI_PREAMBLE(env); @@ -1553,13 +1613,18 @@ napi_status napi_create_type_error(napi_env env, v8::Local message_value = v8impl::V8LocalValueFromJsValue(msg); RETURN_STATUS_IF_FALSE(env, message_value->IsString(), napi_string_expected); - *result = v8impl::JsValueFromV8LocalValue(v8::Exception::TypeError( - message_value.As())); + v8::Local error_obj = + v8::Exception::TypeError(message_value.As()); + napi_status status = set_error_code(env, error_obj, code, nullptr); + if (status != napi_ok) return status; + + *result = v8impl::JsValueFromV8LocalValue(error_obj); return GET_RETURN_STATUS(env); } napi_status napi_create_range_error(napi_env env, + napi_value code, napi_value msg, napi_value* result) { NAPI_PREAMBLE(env); @@ -1569,8 +1634,12 @@ napi_status napi_create_range_error(napi_env env, v8::Local message_value = v8impl::V8LocalValueFromJsValue(msg); RETURN_STATUS_IF_FALSE(env, message_value->IsString(), napi_string_expected); - *result = v8impl::JsValueFromV8LocalValue(v8::Exception::RangeError( - message_value.As())); + v8::Local error_obj = + v8::Exception::RangeError(message_value.As()); + napi_status status = set_error_code(env, error_obj, code, nullptr); + if (status != napi_ok) return status; + + *result = v8impl::JsValueFromV8LocalValue(error_obj); return GET_RETURN_STATUS(env); } @@ -1743,40 +1812,58 @@ napi_status napi_throw(napi_env env, napi_value error) { return napi_clear_last_error(env); } -napi_status napi_throw_error(napi_env env, const char* msg) { +napi_status napi_throw_error(napi_env env, + const char* code, + const char* msg) { NAPI_PREAMBLE(env); v8::Isolate* isolate = env->isolate; v8::Local str; CHECK_NEW_FROM_UTF8(env, str, msg); - isolate->ThrowException(v8::Exception::Error(str)); + v8::Local error_obj = v8::Exception::Error(str); + napi_status status = set_error_code(env, error_obj, nullptr, code); + if (status != napi_ok) return status; + + isolate->ThrowException(error_obj); // any VM calls after this point and before returning // to the javascript invoker will fail return napi_clear_last_error(env); } -napi_status napi_throw_type_error(napi_env env, const char* msg) { +napi_status napi_throw_type_error(napi_env env, + const char* code, + const char* msg) { NAPI_PREAMBLE(env); v8::Isolate* isolate = env->isolate; v8::Local str; CHECK_NEW_FROM_UTF8(env, str, msg); - isolate->ThrowException(v8::Exception::TypeError(str)); + v8::Local error_obj = v8::Exception::TypeError(str); + napi_status status = set_error_code(env, error_obj, nullptr, code); + if (status != napi_ok) return status; + + isolate->ThrowException(error_obj); // any VM calls after this point and before returning // to the javascript invoker will fail return napi_clear_last_error(env); } -napi_status napi_throw_range_error(napi_env env, const char* msg) { +napi_status napi_throw_range_error(napi_env env, + const char* code, + const char* msg) { NAPI_PREAMBLE(env); v8::Isolate* isolate = env->isolate; v8::Local str; CHECK_NEW_FROM_UTF8(env, str, msg); - isolate->ThrowException(v8::Exception::RangeError(str)); + v8::Local error_obj = v8::Exception::RangeError(str); + napi_status status = set_error_code(env, error_obj, nullptr, code); + if (status != napi_ok) return status; + + isolate->ThrowException(error_obj); // any VM calls after this point and before returning // to the javascript invoker will fail return napi_clear_last_error(env); @@ -2415,7 +2502,9 @@ napi_status napi_instanceof(napi_env env, CHECK_TO_OBJECT(env, context, ctor, constructor); if (!ctor->IsFunction()) { - napi_throw_type_error(env, "constructor must be a function"); + napi_throw_type_error(env, + "ERR_NAPI_CONS_FUNCTION", + "Constructor must be a function"); return napi_set_last_error(env, napi_function_expected); } @@ -2483,7 +2572,10 @@ napi_status napi_instanceof(napi_env env, v8::Local prototype_property = maybe_prototype.ToLocalChecked(); if (!prototype_property->IsObject()) { - napi_throw_type_error(env, "constructor.prototype must be an object"); + napi_throw_type_error( + env, + "ERR_NAPI_CONS_PROTOTYPE_OBJECT", + "Constructor.prototype must be an object"); return napi_set_last_error(env, napi_object_expected); } diff --git a/src/node_api.h b/src/node_api.h index d60ddf7466ef1f..f4d097ad104cf9 100644 --- a/src/node_api.h +++ b/src/node_api.h @@ -151,12 +151,15 @@ NAPI_EXTERN napi_status napi_create_function(napi_env env, void* data, napi_value* result); NAPI_EXTERN napi_status napi_create_error(napi_env env, + napi_value code, napi_value msg, napi_value* result); NAPI_EXTERN napi_status napi_create_type_error(napi_env env, + napi_value code, napi_value msg, napi_value* result); NAPI_EXTERN napi_status napi_create_range_error(napi_env env, + napi_value code, napi_value msg, napi_value* result); @@ -413,9 +416,15 @@ NAPI_EXTERN napi_status napi_escape_handle(napi_env env, // Methods to support error handling NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error); -NAPI_EXTERN napi_status napi_throw_error(napi_env env, const char* msg); -NAPI_EXTERN napi_status napi_throw_type_error(napi_env env, const char* msg); -NAPI_EXTERN napi_status napi_throw_range_error(napi_env env, const char* msg); +NAPI_EXTERN napi_status napi_throw_error(napi_env env, + const char* code, + const char* msg); +NAPI_EXTERN napi_status napi_throw_type_error(napi_env env, + const char* code, + const char* msg); +NAPI_EXTERN napi_status napi_throw_range_error(napi_env env, + const char* code, + const char* msg); NAPI_EXTERN napi_status napi_is_error(napi_env env, napi_value value, bool* result); diff --git a/test/addons-napi/common.h b/test/addons-napi/common.h index e9640935d4154b..422418ced49a39 100644 --- a/test/addons-napi/common.h +++ b/test/addons-napi/common.h @@ -12,7 +12,7 @@ const char* error_message = error_info->error_message != NULL ? \ error_info->error_message : \ "empty error message"; \ - napi_throw_error((env), error_message); \ + napi_throw_error((env), NULL, error_message); \ } \ } while (0) @@ -21,6 +21,7 @@ if (!(assertion)) { \ napi_throw_error( \ (env), \ + NULL, \ "assertion (" #assertion ") failed: " message); \ return ret_val; \ } \ diff --git a/test/addons-napi/test_async/test_async.cc b/test/addons-napi/test_async/test_async.cc index cc7bc334304323..f257b268b93159 100644 --- a/test/addons-napi/test_async/test_async.cc +++ b/test/addons-napi/test_async/test_async.cc @@ -29,7 +29,7 @@ void Execute(napi_env env, void* data) { carrier* c = static_cast(data); if (c != &the_carrier) { - napi_throw_type_error(env, "Wrong data parameter to Execute."); + napi_throw_type_error(env, nullptr, "Wrong data parameter to Execute."); return; } @@ -40,12 +40,12 @@ void Complete(napi_env env, napi_status status, void* data) { carrier* c = static_cast(data); if (c != &the_carrier) { - napi_throw_type_error(env, "Wrong data parameter to Complete."); + napi_throw_type_error(env, nullptr, "Wrong data parameter to Complete."); return; } if (status != napi_ok) { - napi_throw_type_error(env, "Execute callback failed."); + napi_throw_type_error(env, nullptr, "Execute callback failed."); return; } diff --git a/test/addons-napi/test_error/test.js b/test/addons-napi/test_error/test.js index f7479f2c9a64d8..80f99f48ba79f3 100644 --- a/test/addons-napi/test_error/test.js +++ b/test/addons-napi/test_error/test.js @@ -72,6 +72,30 @@ assert.throws(() => { test_error.throwTypeError(); }, /^TypeError: type error$/); +assert.throws( + () => test_error.throwErrorCode(), + common.expectsError({ + code: 'ERR_TEST_CODE', + message: 'Error [error]' + }) +); + +assert.throws( + () => test_error.throwRangeErrorCode(), + common.expectsError({ + code: 'ERR_TEST_CODE', + message: 'RangeError [range error]' + }) +); + +assert.throws( + () => test_error.throwTypeErrorCode(), + common.expectsError({ + code: 'ERR_TEST_CODE', + message: 'TypeError [type error]' + }) +); + let error = test_error.createError(); assert.ok(error instanceof Error, 'expected error to be an instance of Error'); assert.strictEqual(error.message, 'error', 'expected message to be "error"'); @@ -89,3 +113,41 @@ assert.ok(error instanceof TypeError, assert.strictEqual(error.message, 'type error', 'expected message to be "type error"'); + +error = test_error.createErrorCode(); +assert.ok(error instanceof Error, 'expected error to be an instance of Error'); +assert.strictEqual(error.code, + 'ERR_TEST_CODE', + 'expected code to be "ERR_TEST_CODE"'); +assert.strictEqual(error.message, + 'Error [error]', + 'expected message to be "Error [error]"'); +assert.strictEqual(error.name, + 'Error [ERR_TEST_CODE]', + 'expected name to be "Error [ERR_TEST_CODE]"'); + +error = test_error.createRangeErrorCode(); +assert.ok(error instanceof RangeError, + 'expected error to be an instance of RangeError'); +assert.strictEqual(error.message, + 'RangeError [range error]', + 'expected message to be "RangeError [range error]"'); +assert.strictEqual(error.code, + 'ERR_TEST_CODE', + 'expected code to be "ERR_TEST_CODE"'); +assert.strictEqual(error.name, + 'RangeError [ERR_TEST_CODE]', + 'expected name to be "RangeError[ERR_TEST_CODE]"'); + +error = test_error.createTypeErrorCode(); +assert.ok(error instanceof TypeError, + 'expected error to be an instance of TypeError'); +assert.strictEqual(error.message, + 'TypeError [type error]', + 'expected message to be "TypeError [type error]"'); +assert.strictEqual(error.code, + 'ERR_TEST_CODE', + 'expected code to be "ERR_TEST_CODE"'); +assert.strictEqual(error.name, + 'TypeError [ERR_TEST_CODE]', + 'expected name to be "TypeError[ERR_TEST_CODE]"'); diff --git a/test/addons-napi/test_error/test_error.cc b/test/addons-napi/test_error/test_error.cc index ddba2059f23be6..29aba1f1ef62f6 100644 --- a/test/addons-napi/test_error/test_error.cc +++ b/test/addons-napi/test_error/test_error.cc @@ -19,31 +19,51 @@ napi_value throwExistingError(napi_env env, napi_callback_info info) { napi_value message; napi_value error; NAPI_CALL(env, napi_create_string_utf8(env, "existing error", -1, &message)); - NAPI_CALL(env, napi_create_error(env, message, &error)); + NAPI_CALL(env, napi_create_error(env, nullptr, message, &error)); NAPI_CALL(env, napi_throw(env, error)); return nullptr; } napi_value throwError(napi_env env, napi_callback_info info) { - NAPI_CALL(env, napi_throw_error(env, "error")); + NAPI_CALL(env, napi_throw_error(env, nullptr, "error")); return nullptr; } napi_value throwRangeError(napi_env env, napi_callback_info info) { - NAPI_CALL(env, napi_throw_range_error(env, "range error")); + NAPI_CALL(env, napi_throw_range_error(env, nullptr, "range error")); return nullptr; } napi_value throwTypeError(napi_env env, napi_callback_info info) { - NAPI_CALL(env, napi_throw_type_error(env, "type error")); + NAPI_CALL(env, napi_throw_type_error(env, nullptr, "type error")); return nullptr; } +napi_value throwErrorCode(napi_env env, napi_callback_info info) { + NAPI_CALL(env, napi_throw_error(env, "ERR_TEST_CODE", "Error [error]")); + return nullptr; +} + +napi_value throwRangeErrorCode(napi_env env, napi_callback_info info) { + NAPI_CALL(env, napi_throw_range_error(env, + "ERR_TEST_CODE", + "RangeError [range error]")); + return nullptr; +} + +napi_value throwTypeErrorCode(napi_env env, napi_callback_info info) { + NAPI_CALL(env, napi_throw_type_error(env, + "ERR_TEST_CODE", + "TypeError [type error]")); + return nullptr; +} + + napi_value createError(napi_env env, napi_callback_info info) { napi_value result; napi_value message; NAPI_CALL(env, napi_create_string_utf8(env, "error", -1, &message)); - NAPI_CALL(env, napi_create_error(env, message, &result)); + NAPI_CALL(env, napi_create_error(env, nullptr, message, &result)); return result; } @@ -51,7 +71,7 @@ napi_value createRangeError(napi_env env, napi_callback_info info) { napi_value result; napi_value message; NAPI_CALL(env, napi_create_string_utf8(env, "range error", -1, &message)); - NAPI_CALL(env, napi_create_range_error(env, message, &result)); + NAPI_CALL(env, napi_create_range_error(env, nullptr, message, &result)); return result; } @@ -59,7 +79,43 @@ napi_value createTypeError(napi_env env, napi_callback_info info) { napi_value result; napi_value message; NAPI_CALL(env, napi_create_string_utf8(env, "type error", -1, &message)); - NAPI_CALL(env, napi_create_type_error(env, message, &result)); + NAPI_CALL(env, napi_create_type_error(env, nullptr, message, &result)); + return result; +} + +napi_value createErrorCode(napi_env env, napi_callback_info info) { + napi_value result; + napi_value message; + napi_value code; + NAPI_CALL(env, napi_create_string_utf8(env, "Error [error]", -1, &message)); + NAPI_CALL(env, napi_create_string_utf8(env, "ERR_TEST_CODE", -1, &code)); + NAPI_CALL(env, napi_create_error(env, code, message, &result)); + return result; +} + +napi_value createRangeErrorCode(napi_env env, napi_callback_info info) { + napi_value result; + napi_value message; + napi_value code; + NAPI_CALL(env, napi_create_string_utf8(env, + "RangeError [range error]", + -1, + &message)); + NAPI_CALL(env, napi_create_string_utf8(env, "ERR_TEST_CODE", -1, &code)); + NAPI_CALL(env, napi_create_range_error(env, code, message, &result)); + return result; +} + +napi_value createTypeErrorCode(napi_env env, napi_callback_info info) { + napi_value result; + napi_value message; + napi_value code; + NAPI_CALL(env, napi_create_string_utf8(env, + "TypeError [type error]", + -1, + &message)); + NAPI_CALL(env, napi_create_string_utf8(env, "ERR_TEST_CODE", -1, &code)); + NAPI_CALL(env, napi_create_type_error(env, code, message, &result)); return result; } @@ -70,9 +126,15 @@ void Init(napi_env env, napi_value exports, napi_value module, void* priv) { DECLARE_NAPI_PROPERTY("throwError", throwError), DECLARE_NAPI_PROPERTY("throwRangeError", throwRangeError), DECLARE_NAPI_PROPERTY("throwTypeError", throwTypeError), + DECLARE_NAPI_PROPERTY("throwErrorCode", throwErrorCode), + DECLARE_NAPI_PROPERTY("throwRangeErrorCode", throwRangeErrorCode), + DECLARE_NAPI_PROPERTY("throwTypeErrorCode", throwTypeErrorCode), DECLARE_NAPI_PROPERTY("createError", createError), DECLARE_NAPI_PROPERTY("createRangeError", createRangeError), DECLARE_NAPI_PROPERTY("createTypeError", createTypeError), + DECLARE_NAPI_PROPERTY("createErrorCode", createErrorCode), + DECLARE_NAPI_PROPERTY("createRangeErrorCode", createRangeErrorCode), + DECLARE_NAPI_PROPERTY("createTypeErrorCode", createTypeErrorCode), }; NAPI_CALL_RETURN_VOID(env, napi_define_properties( diff --git a/test/addons-napi/test_typedarray/test_typedarray.c b/test/addons-napi/test_typedarray/test_typedarray.c index 4194492cae8b3a..ffc118681bad9e 100644 --- a/test/addons-napi/test_typedarray/test_typedarray.c +++ b/test/addons-napi/test_typedarray/test_typedarray.c @@ -65,7 +65,7 @@ napi_value Multiply(napi_env env, napi_callback_info info) { output_doubles[i] = input_doubles[i] * multiplier; } } else { - napi_throw_error(env, "Typed array was of a type not expected by test."); + napi_throw_error(env, NULL, "Typed array was of a type not expected by test."); return NULL; }