Skip to content

Commit 221c8bd

Browse files
TimothyGutargos
authored andcommitted
messaging: use actual DOMException for DataCloneError
PR-URL: #21540 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 3a627c8 commit 221c8bd

5 files changed

Lines changed: 119 additions & 1 deletion

File tree

‎lib/internal/bootstrap/node.js‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@
101101
setupGlobalURL();
102102
}
103103

104+
if(process.binding('config').experimentalWorker){
105+
setupDOMException();
106+
}
107+
104108
// On OpenBSD process.execPath will be relative unless we
105109
// get the full path before process.execPath is used.
106110
if(process.platform==='openbsd'){
@@ -381,6 +385,11 @@
381385
});
382386
}
383387

388+
functionsetupDOMException(){
389+
// Registers the constructor with C++.
390+
NativeModule.require('internal/domexception');
391+
}
392+
384393
functionsetupInspector(originalConsole,wrappedConsole,CJSModule){
385394
if(!process.config.variables.v8_enable_inspector){
386395
return;

‎lib/internal/domexception.js‎

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
'use strict';
2+
3+
const{ internalBinding }=require('internal/bootstrap/loaders');
4+
const{ registerDOMException }=internalBinding('messaging');
5+
const{ERR_INVALID_THIS}=require('internal/errors').codes;
6+
7+
constinternalsMap=newWeakMap();
8+
9+
constnameToCodeMap=newMap();
10+
11+
classDOMExceptionextendsError{
12+
constructor(message='',name='Error'){
13+
super();
14+
internalsMap.set(this,{
15+
message: `${message}`,
16+
name: `${name}`
17+
});
18+
}
19+
20+
getname(){
21+
constinternals=internalsMap.get(this);
22+
if(internals===undefined){
23+
thrownewERR_INVALID_THIS('DOMException');
24+
}
25+
returninternals.name;
26+
}
27+
28+
getmessage(){
29+
constinternals=internalsMap.get(this);
30+
if(internals===undefined){
31+
thrownewERR_INVALID_THIS('DOMException');
32+
}
33+
returninternals.message;
34+
}
35+
36+
getcode(){
37+
constinternals=internalsMap.get(this);
38+
if(internals===undefined){
39+
thrownewERR_INVALID_THIS('DOMException');
40+
}
41+
constcode=nameToCodeMap.get(internals.name);
42+
returncode===undefined ? 0 : code;
43+
}
44+
}
45+
46+
for(const[name,codeName,value]of[
47+
['IndexSizeError','INDEX_SIZE_ERR',1],
48+
['DOMStringSizeError','DOMSTRING_SIZE_ERR',2],
49+
['HierarchyRequestError','HIERARCHY_REQUEST_ERR',3],
50+
['WrongDocumentError','WRONG_DOCUMENT_ERR',4],
51+
['InvalidCharacterError','INVALID_CHARACTER_ERR',5],
52+
['NoDataAllowedError','NO_DATA_ALLOWED_ERR',6],
53+
['NoModificationAllowedError','NO_MODIFICATION_ALLOWED_ERR',7],
54+
['NotFoundError','NOT_FOUND_ERR',8],
55+
['NotSupportedError','NOT_SUPPORTED_ERR',9],
56+
['InUseAttributeError','INUSE_ATTRIBUTE_ERR',10],
57+
['InvalidStateError','INVALID_STATE_ERR',11],
58+
['SyntaxError','SYNTAX_ERR',12],
59+
['InvalidModificationError','INVALID_MODIFICATION_ERR',13],
60+
['NamespaceError','NAMESPACE_ERR',14],
61+
['InvalidAccessError','INVALID_ACCESS_ERR',15],
62+
['ValidationError','VALIDATION_ERR',16],
63+
['TypeMismatchError','TYPE_MISMATCH_ERR',17],
64+
['SecurityError','SECURITY_ERR',18],
65+
['NetworkError','NETWORK_ERR',19],
66+
['AbortError','ABORT_ERR',20],
67+
['URLMismatchError','URL_MISMATCH_ERR',21],
68+
['QuotaExceededError','QUOTA_EXCEEDED_ERR',22],
69+
['TimeoutError','TIMEOUT_ERR',23],
70+
['InvalidNodeTypeError','INVALID_NODE_TYPE_ERR',24],
71+
['DataCloneError','DATA_CLONE_ERR',25]
72+
// There are some more error names, but since they don't have codes assigned,
73+
// we don't need to care about them.
74+
]){
75+
constdesc={enumerable: true, value };
76+
Object.defineProperty(DOMException,codeName,desc);
77+
Object.defineProperty(DOMException.prototype,codeName,desc);
78+
nameToCodeMap.set(name,value);
79+
}
80+
81+
module.exports=DOMException;
82+
83+
registerDOMException(DOMException);

‎node.gyp‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
'lib/internal/constants.js',
107107
'lib/internal/dns/promises.js',
108108
'lib/internal/dns/utils.js',
109+
'lib/internal/domexception.js',
109110
'lib/internal/encoding.js',
110111
'lib/internal/errors.js',
111112
'lib/internal/error-serdes.js',

‎src/env.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ struct PackageConfig {
322322
V(buffer_prototype_object, v8::Object) \
323323
V(context, v8::Context) \
324324
V(domain_callback, v8::Function) \
325+
V(domexception_function, v8::Function) \
325326
V(fdclose_constructor_template, v8::ObjectTemplate) \
326327
V(fd_constructor_template, v8::ObjectTemplate) \
327328
V(filehandlereadwrap_template, v8::ObjectTemplate) \

‎src/node_messaging.cc‎

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,21 @@ void Message::AddMessagePort(std::unique_ptr<MessagePortData>&& data) {
144144

145145
namespace {
146146

147+
voidThrowDataCloneError(Environment* env, Local<String> message) {
148+
Local<Value> argv[] = {
149+
message,
150+
FIXED_ONE_BYTE_STRING(env->isolate(), "DataCloneError")
151+
};
152+
Local<Value> exception;
153+
Local<Function> domexception_ctor = env->domexception_function();
154+
CHECK(!domexception_ctor.IsEmpty());
155+
if (!domexception_ctor->NewInstance(env->context(), arraysize(argv), argv)
156+
.ToLocal(&exception)) {
157+
return;
158+
}
159+
env->isolate()->ThrowException(exception);
160+
}
161+
147162
// This tells V8 how to serialize objects that it does not understand
148163
// (e.g. C++ objects) into the output buffer, in a way that our own
149164
// DeserializerDelegate understands how to unpack.
@@ -153,7 +168,7 @@ class SerializerDelegate : public ValueSerializer::Delegate {
153168
: env_(env), context_(context), msg_(m) {}
154169

155170
voidThrowDataCloneError(Local<String> message) override {
156-
env_->isolate()->ThrowException(Exception::Error(message));
171+
ThrowDataCloneError(env_, message);
157172
}
158173

159174
Maybe<bool> WriteHostObject(Isolate* isolate, Local<Object> object) override {
@@ -688,6 +703,13 @@ static void MessageChannel(const FunctionCallbackInfo<Value>& args) {
688703
.FromJust();
689704
}
690705

706+
staticvoidRegisterDOMException(const FunctionCallbackInfo<Value>& args) {
707+
Environment* env = Environment::GetCurrent(args);
708+
CHECK_EQ(args.Length(), 1);
709+
CHECK(args[0]->IsFunction());
710+
env->set_domexception_function(args[0].As<Function>());
711+
}
712+
691713
staticvoidInitMessaging(Local<Object> target,
692714
Local<Value> unused,
693715
Local<Context> context,
@@ -708,6 +730,8 @@ static void InitMessaging(Local<Object> target,
708730
env->message_port_constructor_string(),
709731
GetMessagePortConstructor(env, context).ToLocalChecked())
710732
.FromJust();
733+
734+
env->SetMethod(target, "registerDOMException", RegisterDOMException);
711735
}
712736

713737
} // anonymous namespace

0 commit comments

Comments
 (0)