Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src,lib: re-implement DOMException as a cloneable native object #41044

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/internal/abort_controller.js
Expand Up @@ -40,7 +40,7 @@ const {

const {
DOMException,
} = internalBinding('messaging');
} = internalBinding('errors');

const {
clearTimeout,
Expand Down
29 changes: 29 additions & 0 deletions lib/internal/errors.js
Expand Up @@ -60,6 +60,12 @@ const {
URIError,
} = primordials;

const {
makeTransferable,
kClone,
kDeserialize,
} = require('internal/worker/js_transferable');

const kIsNodeError = Symbol('kIsNodeError');

const isWindows = process.platform === 'win32';
Expand Down Expand Up @@ -828,6 +834,29 @@ class AbortError extends Error {
super(message, options);
this.code = 'ABORT_ERR';
this.name = 'AbortError';
// eslint-disable-next-line no-constructor-return
return makeTransferable(this);
}

[kClone]() {
const name = this.name;
const message = this.message;
const stack = this.stack;
const code = this.code;
const cause = this.cause;

return {
data: { name, message, stack, code, cause },
deserializeInfo: 'internal/errors:AbortError',
};
}

[kDeserialize]({ name, message, stack, code, cause }) {
this.name = name;
this.message = message;
this.stack = stack;
this.code = code;
this.cause = cause;
}
}
module.exports = {
Expand Down
122 changes: 0 additions & 122 deletions lib/internal/per_context/domexception.js

This file was deleted.

4 changes: 2 additions & 2 deletions lib/internal/util.js
Expand Up @@ -468,12 +468,12 @@ function createDeferredPromise() {

let _DOMException;
const lazyDOMExceptionClass = () => {
_DOMException ??= internalBinding('messaging').DOMException;
_DOMException ??= internalBinding('errors').DOMException;
return _DOMException;
};

const lazyDOMException = hideStackFrames((message, name) => {
_DOMException ??= internalBinding('messaging').DOMException;
_DOMException ??= internalBinding('errors').DOMException;
return new _DOMException(message, name);
});

Expand Down
2 changes: 1 addition & 1 deletion lib/internal/webstreams/readablestream.js
Expand Up @@ -40,7 +40,7 @@ const {

const {
DOMException,
} = internalBinding('messaging');
} = internalBinding('errors');

const {
isArrayBufferView,
Expand Down
88 changes: 3 additions & 85 deletions lib/internal/webstreams/transfer.js
@@ -1,9 +1,7 @@
'use strict';

const {
ObjectDefineProperties,
PromiseResolve,
ReflectConstruct,
} = primordials;

const {
Expand All @@ -13,7 +11,7 @@ const {

const {
DOMException,
} = internalBinding('messaging');
} = internalBinding('errors');

const {
ReadableStream,
Expand All @@ -34,72 +32,6 @@ const {

const assert = require('internal/assert');

const {
makeTransferable,
kClone,
kDeserialize,
} = require('internal/worker/js_transferable');

// This class is a bit of a hack. The Node.js implementation of
// DOMException is not transferable/cloneable. This provides us
// with a variant that is. Unfortunately, it means playing around
// a bit with the message, name, and code properties and the
// prototype. We can revisit this if DOMException is ever made
// properly cloneable.
class CloneableDOMException extends DOMException {
constructor(message, name) {
super(message, name);
this[kDeserialize]({
message: this.message,
name: this.name,
code: this.code,
});
// eslint-disable-next-line no-constructor-return
return makeTransferable(this);
}

[kClone]() {
return {
data: {
message: this.message,
name: this.name,
code: this.code,
},
deserializeInfo:
'internal/webstreams/transfer:InternalCloneableDOMException'
};
}

[kDeserialize]({ message, name, code }) {
ObjectDefineProperties(this, {
message: {
configurable: true,
enumerable: true,
get() { return message; },
},
name: {
configurable: true,
enumerable: true,
get() { return name; },
},
code: {
configurable: true,
enumerable: true,
get() { return code; },
},
});
}
}

function InternalCloneableDOMException() {
return makeTransferable(
ReflectConstruct(
CloneableDOMException,
[],
DOMException));
}
InternalCloneableDOMException[kDeserialize] = () => {};

class CrossRealmTransformReadableSource {
constructor(port) {
this[kState] = {
Expand Down Expand Up @@ -133,7 +65,7 @@ class CrossRealmTransformReadableSource {
};

port.onmessageerror = () => {
const error = new CloneableDOMException(
const error = new DOMException(
'Internal transferred ReadableStream error',
'DataCloneError');
port.postMessage({ type: 'error', value: error });
Expand All @@ -156,10 +88,6 @@ class CrossRealmTransformReadableSource {
try {
this[kState].port.postMessage({ type: 'error', value: reason });
} catch (error) {
if (error instanceof DOMException) {
// eslint-disable-next-line no-ex-assign
error = new CloneableDOMException(error.message, error.name);
}
this[kState].port.postMessage({ type: 'error', value: error });
throw error;
} finally {
Expand Down Expand Up @@ -200,7 +128,7 @@ class CrossRealmTransformWritableSink {
}
};
port.onmessageerror = () => {
const error = new CloneableDOMException(
const error = new DOMException(
'Internal transferred ReadableStream error',
'DataCloneError');
port.postMessage({ type: 'error', value: error });
Expand Down Expand Up @@ -229,10 +157,6 @@ class CrossRealmTransformWritableSink {
try {
this[kState].port.postMessage({ type: 'chunk', value: chunk });
} catch (error) {
if (error instanceof DOMException) {
// eslint-disable-next-line no-ex-assign
error = new CloneableDOMException(error.message, error.name);
}
this[kState].port.postMessage({ type: 'error', value: error });
this[kState].port.close();
throw error;
Expand All @@ -248,10 +172,6 @@ class CrossRealmTransformWritableSink {
try {
this[kState].port.postMessage({ type: 'error', value: reason });
} catch (error) {
if (error instanceof DOMException) {
// eslint-disable-next-line no-ex-assign
error = new CloneableDOMException(error.message, error.name);
}
this[kState].port.postMessage({ type: 'error', value: error });
throw error;
} finally {
Expand Down Expand Up @@ -294,6 +214,4 @@ module.exports = {
newCrossRealmWritableSink,
CrossRealmTransformWritableSink,
CrossRealmTransformReadableSource,
CloneableDOMException,
InternalCloneableDOMException,
};
2 changes: 1 addition & 1 deletion lib/internal/webstreams/transformstream.js
Expand Up @@ -22,7 +22,7 @@ const {

const {
DOMException,
} = internalBinding('messaging');
} = internalBinding('errors');

const {
createDeferredPromise,
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/webstreams/writablestream.js
Expand Up @@ -28,7 +28,7 @@ const {

const {
DOMException,
} = internalBinding('messaging');
} = internalBinding('errors');

const {
createDeferredPromise,
Expand Down
6 changes: 5 additions & 1 deletion lib/internal/worker/io.js
Expand Up @@ -32,8 +32,12 @@ const {
receiveMessageOnPort: receiveMessageOnPort_,
stopMessagePort,
checkMessagePort,
DOMException,
} = internalBinding('messaging');

const {
DOMException,
} = internalBinding('errors');

const {
getEnvMessagePort
} = internalBinding('worker');
Expand Down
1 change: 0 additions & 1 deletion src/api/environment.cc
Expand Up @@ -669,7 +669,6 @@ Maybe<bool> InitializePrimordials(Local<Context> context) {
}

static const char* context_files[] = {"internal/per_context/primordials",
"internal/per_context/domexception",
"internal/per_context/messageport",
nullptr};

Expand Down