diff --git a/doc/api/errors.md b/doc/api/errors.md
index 131773143ceca7..994634c8067c31 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -703,6 +703,14 @@ non-writable `stdout` or `stderr` stream.
A constructor for a class was called without `new`.
+
+### ERR_CONSTRUCT_CALL_INVALID
+
+
+A class constructor was called that is not callable.
+
### ERR_CPU_USAGE
diff --git a/src/node_errors.h b/src/node_errors.h
index 0dad93f31fa33e..689911f9963a55 100644
--- a/src/node_errors.h
+++ b/src/node_errors.h
@@ -54,7 +54,8 @@ void FatalException(v8::Isolate* isolate,
V(ERR_BUFFER_CONTEXT_NOT_AVAILABLE, Error) \
V(ERR_BUFFER_OUT_OF_BOUNDS, RangeError) \
V(ERR_BUFFER_TOO_LARGE, Error) \
- V(ERR_CONSTRUCT_CALL_REQUIRED, Error) \
+ V(ERR_CONSTRUCT_CALL_REQUIRED, TypeError) \
+ V(ERR_CONSTRUCT_CALL_INVALID, TypeError) \
V(ERR_INVALID_ARG_VALUE, TypeError) \
V(ERR_INVALID_ARG_TYPE, TypeError) \
V(ERR_INVALID_MODULE_SPECIFIER, TypeError) \
@@ -99,6 +100,7 @@ void FatalException(v8::Isolate* isolate,
#define PREDEFINED_ERROR_MESSAGES(V) \
V(ERR_BUFFER_CONTEXT_NOT_AVAILABLE, \
"Buffer is not available for the current Context") \
+ V(ERR_CONSTRUCT_CALL_INVALID, "Constructor cannot be called") \
V(ERR_CONSTRUCT_CALL_REQUIRED, "Cannot call constructor without `new`") \
V(ERR_INVALID_TRANSFER_OBJECT, "Found invalid object in transferList") \
V(ERR_MEMORY_ALLOCATION_FAILED, "Failed to allocate memory") \
diff --git a/src/node_messaging.cc b/src/node_messaging.cc
index 79fa510ed70ab1..7a0f2db8830978 100644
--- a/src/node_messaging.cc
+++ b/src/node_messaging.cc
@@ -529,16 +529,11 @@ void MessagePort::Close(v8::Local close_callback) {
}
void MessagePort::New(const FunctionCallbackInfo& args) {
+ // This constructor just throws an error. Unfortunately, we can’t use V8’s
+ // ConstructorBehavior::kThrow, as that also removes the prototype from the
+ // class (i.e. makes it behave like an arrow function).
Environment* env = Environment::GetCurrent(args);
- if (!args.IsConstructCall()) {
- THROW_ERR_CONSTRUCT_CALL_REQUIRED(env);
- return;
- }
-
- Local context = args.This()->CreationContext();
- Context::Scope context_scope(context);
-
- new MessagePort(env, context, args.This());
+ THROW_ERR_CONSTRUCT_CALL_INVALID(env);
}
MessagePort* MessagePort::New(
@@ -546,16 +541,14 @@ MessagePort* MessagePort::New(
Local context,
std::unique_ptr data) {
Context::Scope context_scope(context);
- Local ctor;
- if (!GetMessagePortConstructor(env, context).ToLocal(&ctor))
- return nullptr;
+ Local ctor_templ = GetMessagePortConstructorTemplate(env);
// Construct a new instance, then assign the listener instance and possibly
// the MessagePortData to it.
Local