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) {