From 03a190f286e18f1b4d2f92a23b350003b83fb316 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Tue, 20 Mar 2018 09:27:45 +0800 Subject: [PATCH] src: add error code helpers to env This commit adds env->THROW_ERR_* and env->ERR_* helpers in the C++ land to quickly assign error codes to existing C++ errors. It also converts several errors in the C++ land that can be assigned either obvious existing error codes, or error codes close to existing ones. The plan is to first assign more error codes before v10, then either migrate the errors into JS land or improve the error messages during v10 without having to go semver-major since they already have error codes assigned. The following new error codes are added: - ERR_INVALID_CONSTRUCTOR_CALL - ERR_SCRIPT_EXECUTION_TIMEOUT (related to ERR_SCRIPT_EXECUTION_INTERRUPTED) --- doc/api/errors.md | 11 ++++++++++ src/env-inl.h | 17 +++++++++++++++ src/env.h | 21 ++++++++++++++++++ src/module_wrap.cc | 32 ++++++++++++++++------------ src/node.cc | 33 +++++++++++++++++------------ src/node_buffer.cc | 17 ++++++++------- src/node_contextify.cc | 34 +++++++++++++++++------------- src/node_crypto.cc | 20 +++++++++--------- src/node_dtrace.cc | 16 +++++++------- src/node_serdes.cc | 12 ++++++----- src/stream_base.cc | 2 +- src/util.h | 8 +++---- test/parallel/test-buffer-alloc.js | 6 +++++- 13 files changed, 150 insertions(+), 79 deletions(-) diff --git a/doc/api/errors.md b/doc/api/errors.md index 62a62d76656223..c7ca32091ad3ac 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -1090,6 +1090,12 @@ A callback function was required but was not been provided to a Node.js API. Invalid characters were detected in headers. + +### ERR_INVALID_CONSTRUCTOR_CALL + +A function that should not be invoked as a construcor was invoked with `new` +or a constructor was invoked without `new`. + ### ERR_INVALID_CURSOR_POS @@ -1343,6 +1349,11 @@ An attempt was made to `require()` an [ES6 module][]. Script execution was interrupted by `SIGINT` (For example, when Ctrl+C was pressed). + +### ERR_SCRIPT_EXECUTION_TIMEOUT + +Script execution timed out, possibly due to bugs in the script being executed. + ### ERR_SERVER_ALREADY_LISTEN diff --git a/src/env-inl.h b/src/env-inl.h index 96e88b5c116adb..ce5d19fa125e81 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -657,6 +657,23 @@ inline void Environment::SetTemplateMethod(v8::Local that, ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) #undef V +#define V(code, type) \ + inline v8::Local Environment::code(const char* message) const { \ + v8::Local js_code = OneByteString(isolate(), #code); \ + v8::Local js_msg = OneByteString(isolate(), message); \ + v8::Local e = \ + v8::Exception::type(js_msg)->ToObject( \ + isolate()->GetCurrentContext()).ToLocalChecked(); \ + e->Set(code_string(), js_code); \ + return e; \ + } \ + \ + inline void Environment::THROW_ ## code(const char* message) const { \ + isolate()->ThrowException(code(message)); \ + } + ENVIRONMENT_ERROR_HELPERS(V) +#undef V + } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS diff --git a/src/env.h b/src/env.h index a688b069242160..68fc4fda139c11 100644 --- a/src/env.h +++ b/src/env.h @@ -343,6 +343,21 @@ struct PackageConfig { V(url_constructor_function, v8::Function) \ V(write_wrap_template, v8::ObjectTemplate) +#define ENVIRONMENT_ERROR_HELPERS(V) \ + V(ERR_BUFFER_OUT_OF_BOUNDS, RangeError) \ + V(ERR_INDEX_OUT_OF_RANGE, RangeError) \ + V(ERR_INSPECTOR_ALREADY_CONNECTED, Error) \ + V(ERR_INVALID_ARG_VALUE, Error) \ + V(ERR_INVALID_ARG_TYPE, TypeError) \ + V(ERR_INVALID_CALLBACK, TypeError) \ + V(ERR_INVALID_CONSTRUCTOR_CALL, TypeError) \ + V(ERR_INVALID_THIS, TypeError) \ + V(ERR_MISSING_ARGS, TypeError) \ + V(ERR_MISSING_MODULE, Error) \ + V(ERR_OUT_OF_RANGE, RangeError) \ + V(ERR_SCRIPT_EXECUTION_INTERRUPTED, Error) \ + V(ERR_SCRIPT_EXECUTION_TIMEOUT, Error) + class Environment; class IsolateData { @@ -716,6 +731,12 @@ class Environment { ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) #undef V +#define V(code, _) \ + inline v8::Local code(const char* message) const; \ + inline void THROW_ ## code(const char* message) const; + ENVIRONMENT_ERROR_HELPERS(V) +#undef V + #if HAVE_INSPECTOR inline inspector::Agent* inspector_agent() const { return inspector_agent_.get(); diff --git a/src/module_wrap.cc b/src/module_wrap.cc index 617bae8b60e3e0..f8639c6a9cb2f0 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -81,19 +81,20 @@ void ModuleWrap::New(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); if (!args.IsConstructCall()) { - env->ThrowError("constructor must be called using new"); + env->THROW_ERR_INVALID_CONSTRUCTOR_CALL( + "constructor must be called using new"); return; } if (!args[0]->IsString()) { - env->ThrowError("first argument is not a string"); + env->THROW_ERR_INVALID_ARG_TYPE("first argument is not a string"); return; } Local source_text = args[0].As(); if (!args[1]->IsString()) { - env->ThrowError("second argument is not a string"); + env->THROW_ERR_INVALID_ARG_TYPE("second argument is not a string"); return; } @@ -162,7 +163,7 @@ void ModuleWrap::Link(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Isolate* isolate = args.GetIsolate(); if (!args[0]->IsFunction()) { - env->ThrowError("first argument is not a function"); + env->THROW_ERR_INVALID_ARG_TYPE("first argument is not a function"); return; } @@ -283,9 +284,10 @@ void ModuleWrap::Evaluate(const FunctionCallbackInfo& args) { // which this timeout is nested, so check whether one of the watchdogs // from this invocation is responsible for termination. if (timed_out) { - env->ThrowError("Script execution timed out."); + env->THROW_ERR_SCRIPT_EXECUTION_TIMEOUT("Script execution timed out."); } else if (received_signal) { - env->ThrowError("Script execution interrupted."); + env->THROW_ERR_SCRIPT_EXECUTION_INTERRUPTED( + "Script execution interrupted."); } env->isolate()->CancelTerminateExecution(); } @@ -666,37 +668,39 @@ void ModuleWrap::Resolve(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.IsConstructCall()) { - env->ThrowError("resolve() must not be called as a constructor"); + env->THROW_ERR_INVALID_CONSTRUCTOR_CALL( + "resolve() must not be called as a constructor"); return; } if (args.Length() != 2) { - env->ThrowError("resolve must have exactly 2 arguments (string, string)"); + env->THROW_ERR_INVALID_ARG_TYPE( + "resolve must have exactly 2 arguments (string, string)"); return; } if (!args[0]->IsString()) { - env->ThrowError("first argument is not a string"); + env->THROW_ERR_INVALID_ARG_TYPE("first argument is not a string"); return; } Utf8Value specifier_utf8(env->isolate(), args[0]); std::string specifier_std(*specifier_utf8, specifier_utf8.length()); if (!args[1]->IsString()) { - env->ThrowError("second argument is not a string"); + env->THROW_ERR_INVALID_ARG_TYPE("second argument is not a string"); return; } Utf8Value url_utf8(env->isolate(), args[1]); URL url(*url_utf8, url_utf8.length()); if (url.flags() & URL_FLAGS_FAILED) { - env->ThrowError("second argument is not a URL string"); + env->THROW_ERR_INVALID_ARG_TYPE("second argument is not a URL string"); return; } Maybe result = node::loader::Resolve(env, specifier_std, url); if (result.IsNothing() || (result.FromJust().flags() & URL_FLAGS_FAILED)) { std::string msg = "Cannot find module " + specifier_std; - env->ThrowError(msg.c_str()); + env->THROW_ERR_MISSING_MODULE(msg.c_str()); return; } @@ -749,7 +753,7 @@ void ModuleWrap::SetImportModuleDynamicallyCallback( Environment* env = Environment::GetCurrent(args); HandleScope handle_scope(iso); if (!args[0]->IsFunction()) { - env->ThrowError("first argument is not a function"); + env->THROW_ERR_INVALID_ARG_TYPE("first argument is not a function"); return; } @@ -782,7 +786,7 @@ void ModuleWrap::SetInitializeImportMetaObjectCallback( Environment* env = Environment::GetCurrent(args); Isolate* isolate = env->isolate(); if (!args[0]->IsFunction()) { - env->ThrowError("first argument is not a function"); + env->THROW_ERR_INVALID_ARG_TYPE("first argument is not a function"); return; } diff --git a/src/node.cc b/src/node.cc index b5084331156bb6..ce80c4a70d2dea 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1577,7 +1577,7 @@ static void Chdir(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() != 1 || !args[0]->IsString()) { - return env->ThrowTypeError("Bad argument."); + return env->THROW_ERR_INVALID_ARG_TYPE("Bad argument."); } node::Utf8Value path(args.GetIsolate(), args[0]); @@ -1619,7 +1619,8 @@ static void Umask(const FunctionCallbackInfo& args) { old = umask(0); umask(static_cast(old)); } else if (!args[0]->IsInt32() && !args[0]->IsString()) { - return env->ThrowTypeError("argument must be an integer or octal string."); + return env->THROW_ERR_INVALID_ARG_TYPE( + "argument must be an integer or octal string."); } else { int oct; if (args[0]->IsInt32()) { @@ -1632,7 +1633,7 @@ static void Umask(const FunctionCallbackInfo& args) { for (size_t i = 0; i < str.length(); i++) { char c = (*str)[i]; if (c > '7' || c < '0') { - return env->ThrowTypeError("invalid octal string"); + return env->THROW_ERR_INVALID_ARG_VALUE("invalid octal string"); } oct *= 8; oct += c - '0'; @@ -1776,7 +1777,8 @@ static void SetGid(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsUint32() && !args[0]->IsString()) { - return env->ThrowTypeError("setgid argument must be a number or a string"); + return env->THROW_ERR_INVALID_ARG_TYPE( + "setgid argument must be a number or a string"); } gid_t gid = gid_by_name(env->isolate(), args[0]); @@ -1795,7 +1797,8 @@ static void SetEGid(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsUint32() && !args[0]->IsString()) { - return env->ThrowTypeError("setegid argument must be a number or string"); + return env->THROW_ERR_INVALID_ARG_TYPE( + "setegid argument must be a number or string"); } gid_t gid = gid_by_name(env->isolate(), args[0]); @@ -1814,7 +1817,8 @@ static void SetUid(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsUint32() && !args[0]->IsString()) { - return env->ThrowTypeError("setuid argument must be a number or a string"); + return env->THROW_ERR_INVALID_ARG_TYPE( + "setuid argument must be a number or a string"); } uid_t uid = uid_by_name(env->isolate(), args[0]); @@ -1833,7 +1837,8 @@ static void SetEUid(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsUint32() && !args[0]->IsString()) { - return env->ThrowTypeError("seteuid argument must be a number or string"); + return env->THROW_ERR_INVALID_ARG_TYPE( + "seteuid argument must be a number or string"); } uid_t uid = uid_by_name(env->isolate(), args[0]); @@ -1890,7 +1895,7 @@ static void SetGroups(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsArray()) { - return env->ThrowTypeError("argument 1 must be an array"); + return env->THROW_ERR_INVALID_ARG_TYPE("argument 1 must be an array"); } Local groups_list = args[0].As(); @@ -1921,11 +1926,13 @@ static void InitGroups(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsUint32() && !args[0]->IsString()) { - return env->ThrowTypeError("argument 1 must be a number or a string"); + return env->THROW_ERR_INVALID_ARG_TYPE( + "argument 1 must be a number or a string"); } if (!args[1]->IsUint32() && !args[1]->IsString()) { - return env->ThrowTypeError("argument 2 must be a number or a string"); + return env->THROW_ERR_INVALID_ARG_TYPE( + "argument 2 must be a number or a string"); } node::Utf8Value arg0(env->isolate(), args[0]); @@ -2040,7 +2047,7 @@ static void Kill(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (args.Length() != 2) { - return env->ThrowError("Bad argument."); + return env->THROW_ERR_MISSING_ARGS("Bad argument."); } int pid = args[0]->Int32Value(); @@ -2238,13 +2245,13 @@ static void DLOpen(const FunctionCallbackInfo& args) { CHECK_EQ(modpending, nullptr); if (args.Length() < 2) { - env->ThrowError("process.dlopen needs at least 2 arguments."); + env->THROW_ERR_MISSING_ARGS("process.dlopen needs at least 2 arguments."); return; } int32_t flags = DLib::kDefaultFlags; if (args.Length() > 2 && !args[2]->Int32Value(context).To(&flags)) { - return env->ThrowTypeError("flag argument must be an integer."); + return env->THROW_ERR_INVALID_ARG_TYPE("flag argument must be an integer."); } Local module; diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 15e6c7a0c492d3..853ab22da0f0be 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -36,9 +36,9 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define THROW_AND_RETURN_IF_OOB(r) \ - do { \ - if (!(r)) return env->ThrowRangeError("Index out of range"); \ +#define THROW_AND_RETURN_IF_OOB(r) \ + do { \ + if (!(r)) return env->THROW_ERR_INDEX_OUT_OF_RANGE("Index out of range"); \ } while (0) #define SLICE_START_END(start_arg, end_arg, end_max) \ @@ -544,7 +544,7 @@ void Copy(const FunctionCallbackInfo &args) { return args.GetReturnValue().Set(0); if (source_start > ts_obj_length) - return env->ThrowRangeError("Index out of range"); + return env->THROW_ERR_INDEX_OUT_OF_RANGE("Index out of range"); if (source_end - source_start > target_length - target_start) source_end = source_start + target_length - target_start; @@ -657,7 +657,7 @@ void StringWrite(const FunctionCallbackInfo& args) { SPREAD_BUFFER_ARG(args.This(), ts_obj); if (!args[0]->IsString()) - return env->ThrowTypeError("Argument must be a string"); + return env->THROW_ERR_INVALID_ARG_TYPE("Argument must be a string"); Local str = args[0]->ToString(env->context()).ToLocalChecked(); @@ -666,7 +666,8 @@ void StringWrite(const FunctionCallbackInfo& args) { THROW_AND_RETURN_IF_OOB(ParseArrayIndex(args[1], 0, &offset)); if (offset > ts_obj_length) - return env->ThrowRangeError("Offset is out of bounds"); + return env->THROW_ERR_BUFFER_OUT_OF_BOUNDS( + "\"offset\" is outside of buffer bounds"); THROW_AND_RETURN_IF_OOB(ParseArrayIndex(args[2], ts_obj_length - offset, &max_length)); @@ -728,9 +729,9 @@ void CompareOffset(const FunctionCallbackInfo &args) { THROW_AND_RETURN_IF_OOB(ParseArrayIndex(args[5], ts_obj_length, &source_end)); if (source_start > ts_obj_length) - return env->ThrowRangeError("Index out of range"); + return env->THROW_ERR_INDEX_OUT_OF_RANGE("Index out of range"); if (target_start > target_length) - return env->ThrowRangeError("Index out of range"); + return env->THROW_ERR_INDEX_OUT_OF_RANGE("Index out of range"); CHECK_LE(source_start, source_end); CHECK_LE(target_start, target_end); diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 42f66885bb85e9..889b9fd453e874 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -242,7 +242,8 @@ void ContextifyContext::MakeContext(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsObject()) { - return env->ThrowTypeError("sandbox argument must be an object."); + return env->THROW_ERR_INVALID_ARG_TYPE( + "sandbox argument must be an object."); } Local sandbox = args[0].As(); @@ -609,7 +610,7 @@ Maybe GetBreakOnSigintArg(Environment* env, return Just(false); } if (!options->IsObject()) { - env->ThrowTypeError("options must be an object"); + env->THROW_ERR_INVALID_ARG_TYPE("options must be an object"); return Nothing(); } @@ -628,7 +629,7 @@ Maybe GetTimeoutArg(Environment* env, Local options) { return Just(-1); } if (!options->IsObject()) { - env->ThrowTypeError("options must be an object"); + env->THROW_ERR_INVALID_ARG_TYPE("options must be an object"); return Nothing(); } @@ -645,7 +646,7 @@ Maybe GetTimeoutArg(Environment* env, Local options) { Maybe timeout = value->IntegerValue(env->context()); if (timeout.IsJust() && timeout.ToChecked() <= 0) { - env->ThrowRangeError("timeout must be a positive number"); + env->THROW_ERR_OUT_OF_RANGE("timeout must be a positive number"); return Nothing(); } @@ -708,7 +709,7 @@ MaybeLocal GetContextArg(Environment* env, if (!value->IsObject()) { if (!value->IsNullOrUndefined()) { - env->ThrowTypeError( + env->THROW_ERR_INVALID_ARG_TYPE( "contextifiedSandbox argument must be an object."); } return MaybeLocal(); @@ -718,7 +719,7 @@ MaybeLocal GetContextArg(Environment* env, ContextifyContext::ContextFromContextifiedSandbox( env, value.As()); if (!sandbox) { - env->ThrowTypeError( + env->THROW_ERR_INVALID_ARG_TYPE( "sandbox argument must have been converted to a context."); return MaybeLocal(); } @@ -737,7 +738,7 @@ Maybe GetDisplayErrorsArg(Environment* env, return Just(true); } if (!options->IsObject()) { - env->ThrowTypeError("options must be an object"); + env->THROW_ERR_INVALID_ARG_TYPE("options must be an object"); return Nothing(); } @@ -766,7 +767,7 @@ MaybeLocal GetFilenameArg(Environment* env, return options.As(); } if (!options->IsObject()) { - env->ThrowTypeError("options must be an object"); + env->THROW_ERR_INVALID_ARG_TYPE("options must be an object"); return Local(); } @@ -799,7 +800,8 @@ MaybeLocal GetCachedData(Environment* env, } if (!value->IsUint8Array()) { - env->ThrowTypeError("options.cachedData must be a Buffer instance"); + env->THROW_ERR_INVALID_ARG_TYPE( + "options.cachedData must be a Buffer instance"); return MaybeLocal(); } @@ -860,7 +862,8 @@ class ContextifyScript : public BaseObject { Environment* env = Environment::GetCurrent(args); if (!args.IsConstructCall()) { - return env->ThrowError("Must call vm.Script as a constructor."); + return env->THROW_ERR_INVALID_CONSTRUCTOR_CALL( + "Must call vm.Script as a constructor."); } ContextifyScript* contextify_script = @@ -981,7 +984,7 @@ class ContextifyScript : public BaseObject { // Assemble arguments if (!args[0]->IsObject()) { - return env->ThrowTypeError( + return env->THROW_ERR_INVALID_ARG_TYPE( "contextifiedSandbox argument must be an object."); } @@ -1005,7 +1008,7 @@ class ContextifyScript : public BaseObject { ContextifyContext* contextify_context = ContextifyContext::ContextFromContextifiedSandbox(env, sandbox); if (contextify_context == nullptr) { - return env->ThrowTypeError( + return env->THROW_ERR_INVALID_ARG_TYPE( "sandbox argument must have been converted to a context."); } @@ -1075,7 +1078,7 @@ class ContextifyScript : public BaseObject { const FunctionCallbackInfo& args, TryCatch* try_catch) { if (!ContextifyScript::InstanceOf(env, args.Holder())) { - env->ThrowTypeError( + env->THROW_ERR_INVALID_THIS( "Script methods can only be called on script instances."); return false; } @@ -1108,9 +1111,10 @@ class ContextifyScript : public BaseObject { // which this timeout is nested, so check whether one of the watchdogs // from this invocation is responsible for termination. if (timed_out) { - env->ThrowError("Script execution timed out."); + env->THROW_ERR_SCRIPT_EXECUTION_TIMEOUT("Script execution timed out."); } else if (received_signal) { - env->ThrowError("Script execution interrupted."); + env->THROW_ERR_SCRIPT_EXECUTION_INTERRUPTED( + "Script execution interrupted."); } env->isolate()->CancelTerminateExecution(); } diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 57dbe6861dc9cd..41c94ad13029c3 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -44,18 +44,18 @@ #include #include -#define THROW_AND_RETURN_IF_NOT_BUFFER(val, prefix) \ - do { \ - if (!Buffer::HasInstance(val)) { \ - return env->ThrowTypeError(prefix " must be a buffer"); \ - } \ +#define THROW_AND_RETURN_IF_NOT_BUFFER(val, prefix) \ + do { \ + if (!Buffer::HasInstance(val)) { \ + return env->THROW_ERR_INVALID_ARG_TYPE(prefix " must be a buffer"); \ + } \ } while (0) -#define THROW_AND_RETURN_IF_NOT_STRING(val, prefix) \ - do { \ - if (!val->IsString()) { \ - return env->ThrowTypeError(prefix " must be a string"); \ - } \ +#define THROW_AND_RETURN_IF_NOT_STRING(val, prefix) \ + do { \ + if (!val->IsString()) { \ + return env->THROW_ERR_INVALID_ARG_TYPE(prefix " must be a string"); \ + } \ } while (0) static const char PUBLIC_KEY_PFX[] = "-----BEGIN PUBLIC KEY-----"; diff --git a/src/node_dtrace.cc b/src/node_dtrace.cc index ed063fddfafc49..d47c3b639c2dcb 100644 --- a/src/node_dtrace.cc +++ b/src/node_dtrace.cc @@ -60,7 +60,7 @@ using v8::Value; #define SLURP_STRING(obj, member, valp) \ if (!(obj)->IsObject()) { \ - return env->ThrowError( \ + return env->THROW_ERR_INVALID_ARG_TYPE( \ "expected object for " #obj " to contain string member " #member); \ } \ node::Utf8Value _##member(env->isolate(), \ @@ -70,7 +70,7 @@ using v8::Value; #define SLURP_INT(obj, member, valp) \ if (!(obj)->IsObject()) { \ - return env->ThrowError( \ + return env->THROW_ERR_INVALID_ARG_TYPE( \ "expected object for " #obj " to contain integer member " #member); \ } \ *valp = obj->Get(OneByteString(env->isolate(), #member)) \ @@ -78,14 +78,14 @@ using v8::Value; #define SLURP_OBJECT(obj, member, valp) \ if (!(obj)->IsObject()) { \ - return env->ThrowError( \ + return env->THROW_ERR_INVALID_ARG_TYPE( \ "expected object for " #obj " to contain object member " #member); \ } \ *valp = Local::Cast(obj->Get(OneByteString(env->isolate(), #member))); #define SLURP_CONNECTION(arg, conn) \ if (!(arg)->IsObject()) { \ - return env->ThrowError( \ + return env->THROW_ERR_INVALID_ARG_TYPE( \ "expected argument " #arg " to be a connection object"); \ } \ node_dtrace_connection_t conn; \ @@ -103,7 +103,7 @@ using v8::Value; #define SLURP_CONNECTION_HTTP_CLIENT(arg, conn) \ if (!(arg)->IsObject()) { \ - return env->ThrowError( \ + return env->THROW_ERR_INVALID_ARG_TYPE( \ "expected argument " #arg " to be a connection object"); \ } \ node_dtrace_connection_t conn; \ @@ -115,11 +115,11 @@ using v8::Value; #define SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(arg0, arg1, conn) \ if (!(arg0)->IsObject()) { \ - return env->ThrowError( \ + return env->THROW_ERR_INVALID_ARG_TYPE( \ "expected argument " #arg0 " to be a connection object"); \ } \ if (!(arg1)->IsObject()) { \ - return env->ThrowError( \ + return env->THROW_ERR_INVALID_ARG_TYPE( \ "expected argument " #arg1 " to be a connection object"); \ } \ node_dtrace_connection_t conn; \ @@ -166,7 +166,7 @@ void DTRACE_HTTP_SERVER_REQUEST(const FunctionCallbackInfo& args) { SLURP_OBJECT(arg0, headers, &headers); if (!(headers)->IsObject()) { - return env->ThrowError( + return env->THROW_ERR_INVALID_ARG_TYPE( "expected object for request to contain string member headers"); } diff --git a/src/node_serdes.cc b/src/node_serdes.cc index 1995eb1b9b506b..dff4f12b3ce1a0 100644 --- a/src/node_serdes.cc +++ b/src/node_serdes.cc @@ -209,7 +209,8 @@ void SerializerContext::TransferArrayBuffer( if (id.IsNothing()) return; if (!args[1]->IsArrayBuffer()) - return ctx->env()->ThrowTypeError("arrayBuffer must be an ArrayBuffer"); + return ctx->env()->THROW_ERR_INVALID_ARG_TYPE( + "arrayBuffer must be an ArrayBuffer"); Local ab = args[1].As(); ctx->serializer_.TransferArrayBuffer(id.FromJust(), ab); @@ -255,7 +256,8 @@ void SerializerContext::WriteRawBytes(const FunctionCallbackInfo& args) { ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder()); if (!args[0]->IsUint8Array()) { - return ctx->env()->ThrowTypeError("source must be a Uint8Array"); + return ctx->env()->THROW_ERR_INVALID_ARG_TYPE( + "source must be a Uint8Array"); } ctx->serializer_.WriteRawBytes(Buffer::Data(args[0]), @@ -305,7 +307,7 @@ void DeserializerContext::New(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[0]->IsUint8Array()) { - return env->ThrowTypeError("buffer must be a Uint8Array"); + return env->THROW_ERR_INVALID_ARG_TYPE("buffer must be a Uint8Array"); } new DeserializerContext(env, args.This(), args[0]); @@ -349,8 +351,8 @@ void DeserializerContext::TransferArrayBuffer( return; } - return ctx->env()->ThrowTypeError("arrayBuffer must be an ArrayBuffer or " - "SharedArrayBuffer"); + return ctx->env()->THROW_ERR_INVALID_ARG_TYPE( + "arrayBuffer must be an ArrayBuffer or SharedArrayBuffer"); } void DeserializerContext::GetWireFormatVersion( diff --git a/src/stream_base.cc b/src/stream_base.cc index 263943d2b03420..3cdce654f3ca86 100644 --- a/src/stream_base.cc +++ b/src/stream_base.cc @@ -174,7 +174,7 @@ int StreamBase::WriteBuffer(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); if (!args[1]->IsUint8Array()) { - env->ThrowTypeError("Second argument must be a buffer"); + env->THROW_ERR_INVALID_ARG_TYPE("Second argument must be a buffer"); return 0; } diff --git a/src/util.h b/src/util.h index e871fc63a5c46a..e2a9721aed45d5 100644 --- a/src/util.h +++ b/src/util.h @@ -414,10 +414,10 @@ class BufferValue : public MaybeStackBuffer { explicit BufferValue(v8::Isolate* isolate, v8::Local value); }; -#define THROW_AND_RETURN_UNLESS_BUFFER(env, obj) \ - do { \ - if (!Buffer::HasInstance(obj)) \ - return env->ThrowTypeError("argument should be a Buffer"); \ +#define THROW_AND_RETURN_UNLESS_BUFFER(env, obj) \ + do { \ + if (!Buffer::HasInstance(obj)) \ + return env->THROW_ERR_INVALID_ARG_TYPE("argument should be a Buffer"); \ } while (0) #define SPREAD_BUFFER_ARG(val, name) \ diff --git a/test/parallel/test-buffer-alloc.js b/test/parallel/test-buffer-alloc.js index 30baa30319f116..69e0721ff24bff 100644 --- a/test/parallel/test-buffer-alloc.js +++ b/test/parallel/test-buffer-alloc.js @@ -982,7 +982,11 @@ common.expectsError(() => { const a = Buffer.alloc(1); const b = Buffer.alloc(1); a.copy(b, 0, 0x100000000, 0x100000001); -}, { code: undefined, type: RangeError, message: 'Index out of range' }); +}, { + code: 'ERR_INDEX_OUT_OF_RANGE', + type: RangeError, + message: 'Index out of range' +}); // Unpooled buffer (replaces SlowBuffer) {