messaging: use actual DOMException for DataCloneError
PR-URL: https://github.com/nodejs/node/pull/21540 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
602da6492f
commit
5f3bdb016a
@ -125,6 +125,10 @@
|
|||||||
setupGlobalURL();
|
setupGlobalURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (process.binding('config').experimentalWorker) {
|
||||||
|
setupDOMException();
|
||||||
|
}
|
||||||
|
|
||||||
// On OpenBSD process.execPath will be relative unless we
|
// On OpenBSD process.execPath will be relative unless we
|
||||||
// get the full path before process.execPath is used.
|
// get the full path before process.execPath is used.
|
||||||
if (process.platform === 'openbsd') {
|
if (process.platform === 'openbsd') {
|
||||||
@ -405,6 +409,11 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupDOMException() {
|
||||||
|
// Registers the constructor with C++.
|
||||||
|
NativeModule.require('internal/domexception');
|
||||||
|
}
|
||||||
|
|
||||||
function setupInspector(originalConsole, wrappedConsole, CJSModule) {
|
function setupInspector(originalConsole, wrappedConsole, CJSModule) {
|
||||||
if (!process.config.variables.v8_enable_inspector) {
|
if (!process.config.variables.v8_enable_inspector) {
|
||||||
return;
|
return;
|
||||||
|
83
lib/internal/domexception.js
Normal file
83
lib/internal/domexception.js
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { internalBinding } = require('internal/bootstrap/loaders');
|
||||||
|
const { registerDOMException } = internalBinding('messaging');
|
||||||
|
const { ERR_INVALID_THIS } = require('internal/errors').codes;
|
||||||
|
|
||||||
|
const internalsMap = new WeakMap();
|
||||||
|
|
||||||
|
const nameToCodeMap = new Map();
|
||||||
|
|
||||||
|
class DOMException extends Error {
|
||||||
|
constructor(message = '', name = 'Error') {
|
||||||
|
super();
|
||||||
|
internalsMap.set(this, {
|
||||||
|
message: `${message}`,
|
||||||
|
name: `${name}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
const internals = internalsMap.get(this);
|
||||||
|
if (internals === undefined) {
|
||||||
|
throw new ERR_INVALID_THIS('DOMException');
|
||||||
|
}
|
||||||
|
return internals.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
get message() {
|
||||||
|
const internals = internalsMap.get(this);
|
||||||
|
if (internals === undefined) {
|
||||||
|
throw new ERR_INVALID_THIS('DOMException');
|
||||||
|
}
|
||||||
|
return internals.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
get code() {
|
||||||
|
const internals = internalsMap.get(this);
|
||||||
|
if (internals === undefined) {
|
||||||
|
throw new ERR_INVALID_THIS('DOMException');
|
||||||
|
}
|
||||||
|
const code = nameToCodeMap.get(internals.name);
|
||||||
|
return code === undefined ? 0 : code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [name, codeName, value] of [
|
||||||
|
['IndexSizeError', 'INDEX_SIZE_ERR', 1],
|
||||||
|
['DOMStringSizeError', 'DOMSTRING_SIZE_ERR', 2],
|
||||||
|
['HierarchyRequestError', 'HIERARCHY_REQUEST_ERR', 3],
|
||||||
|
['WrongDocumentError', 'WRONG_DOCUMENT_ERR', 4],
|
||||||
|
['InvalidCharacterError', 'INVALID_CHARACTER_ERR', 5],
|
||||||
|
['NoDataAllowedError', 'NO_DATA_ALLOWED_ERR', 6],
|
||||||
|
['NoModificationAllowedError', 'NO_MODIFICATION_ALLOWED_ERR', 7],
|
||||||
|
['NotFoundError', 'NOT_FOUND_ERR', 8],
|
||||||
|
['NotSupportedError', 'NOT_SUPPORTED_ERR', 9],
|
||||||
|
['InUseAttributeError', 'INUSE_ATTRIBUTE_ERR', 10],
|
||||||
|
['InvalidStateError', 'INVALID_STATE_ERR', 11],
|
||||||
|
['SyntaxError', 'SYNTAX_ERR', 12],
|
||||||
|
['InvalidModificationError', 'INVALID_MODIFICATION_ERR', 13],
|
||||||
|
['NamespaceError', 'NAMESPACE_ERR', 14],
|
||||||
|
['InvalidAccessError', 'INVALID_ACCESS_ERR', 15],
|
||||||
|
['ValidationError', 'VALIDATION_ERR', 16],
|
||||||
|
['TypeMismatchError', 'TYPE_MISMATCH_ERR', 17],
|
||||||
|
['SecurityError', 'SECURITY_ERR', 18],
|
||||||
|
['NetworkError', 'NETWORK_ERR', 19],
|
||||||
|
['AbortError', 'ABORT_ERR', 20],
|
||||||
|
['URLMismatchError', 'URL_MISMATCH_ERR', 21],
|
||||||
|
['QuotaExceededError', 'QUOTA_EXCEEDED_ERR', 22],
|
||||||
|
['TimeoutError', 'TIMEOUT_ERR', 23],
|
||||||
|
['InvalidNodeTypeError', 'INVALID_NODE_TYPE_ERR', 24],
|
||||||
|
['DataCloneError', 'DATA_CLONE_ERR', 25]
|
||||||
|
// There are some more error names, but since they don't have codes assigned,
|
||||||
|
// we don't need to care about them.
|
||||||
|
]) {
|
||||||
|
const desc = { enumerable: true, value };
|
||||||
|
Object.defineProperty(DOMException, codeName, desc);
|
||||||
|
Object.defineProperty(DOMException.prototype, codeName, desc);
|
||||||
|
nameToCodeMap.set(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = DOMException;
|
||||||
|
|
||||||
|
registerDOMException(DOMException);
|
1
node.gyp
1
node.gyp
@ -106,6 +106,7 @@
|
|||||||
'lib/internal/constants.js',
|
'lib/internal/constants.js',
|
||||||
'lib/internal/dns/promises.js',
|
'lib/internal/dns/promises.js',
|
||||||
'lib/internal/dns/utils.js',
|
'lib/internal/dns/utils.js',
|
||||||
|
'lib/internal/domexception.js',
|
||||||
'lib/internal/encoding.js',
|
'lib/internal/encoding.js',
|
||||||
'lib/internal/errors.js',
|
'lib/internal/errors.js',
|
||||||
'lib/internal/error-serdes.js',
|
'lib/internal/error-serdes.js',
|
||||||
|
@ -322,6 +322,7 @@ struct PackageConfig {
|
|||||||
V(buffer_prototype_object, v8::Object) \
|
V(buffer_prototype_object, v8::Object) \
|
||||||
V(context, v8::Context) \
|
V(context, v8::Context) \
|
||||||
V(domain_callback, v8::Function) \
|
V(domain_callback, v8::Function) \
|
||||||
|
V(domexception_function, v8::Function) \
|
||||||
V(fdclose_constructor_template, v8::ObjectTemplate) \
|
V(fdclose_constructor_template, v8::ObjectTemplate) \
|
||||||
V(fd_constructor_template, v8::ObjectTemplate) \
|
V(fd_constructor_template, v8::ObjectTemplate) \
|
||||||
V(filehandlereadwrap_template, v8::ObjectTemplate) \
|
V(filehandlereadwrap_template, v8::ObjectTemplate) \
|
||||||
|
@ -144,6 +144,21 @@ void Message::AddMessagePort(std::unique_ptr<MessagePortData>&& data) {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
void ThrowDataCloneError(Environment* env, Local<String> message) {
|
||||||
|
Local<Value> argv[] = {
|
||||||
|
message,
|
||||||
|
FIXED_ONE_BYTE_STRING(env->isolate(), "DataCloneError")
|
||||||
|
};
|
||||||
|
Local<Value> exception;
|
||||||
|
Local<Function> domexception_ctor = env->domexception_function();
|
||||||
|
CHECK(!domexception_ctor.IsEmpty());
|
||||||
|
if (!domexception_ctor->NewInstance(env->context(), arraysize(argv), argv)
|
||||||
|
.ToLocal(&exception)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
env->isolate()->ThrowException(exception);
|
||||||
|
}
|
||||||
|
|
||||||
// This tells V8 how to serialize objects that it does not understand
|
// This tells V8 how to serialize objects that it does not understand
|
||||||
// (e.g. C++ objects) into the output buffer, in a way that our own
|
// (e.g. C++ objects) into the output buffer, in a way that our own
|
||||||
// DeserializerDelegate understands how to unpack.
|
// DeserializerDelegate understands how to unpack.
|
||||||
@ -153,7 +168,7 @@ class SerializerDelegate : public ValueSerializer::Delegate {
|
|||||||
: env_(env), context_(context), msg_(m) {}
|
: env_(env), context_(context), msg_(m) {}
|
||||||
|
|
||||||
void ThrowDataCloneError(Local<String> message) override {
|
void ThrowDataCloneError(Local<String> message) override {
|
||||||
env_->isolate()->ThrowException(Exception::Error(message));
|
ThrowDataCloneError(env_, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<bool> WriteHostObject(Isolate* isolate, Local<Object> object) override {
|
Maybe<bool> WriteHostObject(Isolate* isolate, Local<Object> object) override {
|
||||||
@ -688,6 +703,13 @@ static void MessageChannel(const FunctionCallbackInfo<Value>& args) {
|
|||||||
.FromJust();
|
.FromJust();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void RegisterDOMException(const FunctionCallbackInfo<Value>& args) {
|
||||||
|
Environment* env = Environment::GetCurrent(args);
|
||||||
|
CHECK_EQ(args.Length(), 1);
|
||||||
|
CHECK(args[0]->IsFunction());
|
||||||
|
env->set_domexception_function(args[0].As<Function>());
|
||||||
|
}
|
||||||
|
|
||||||
static void InitMessaging(Local<Object> target,
|
static void InitMessaging(Local<Object> target,
|
||||||
Local<Value> unused,
|
Local<Value> unused,
|
||||||
Local<Context> context,
|
Local<Context> context,
|
||||||
@ -708,6 +730,8 @@ static void InitMessaging(Local<Object> target,
|
|||||||
env->message_port_constructor_string(),
|
env->message_port_constructor_string(),
|
||||||
GetMessagePortConstructor(env, context).ToLocalChecked())
|
GetMessagePortConstructor(env, context).ToLocalChecked())
|
||||||
.FromJust();
|
.FromJust();
|
||||||
|
|
||||||
|
env->SetMethod(target, "registerDOMException", RegisterDOMException);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user