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

lib: reuse invalid state errors on webstreams #46086

Merged
Merged
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
38 changes: 32 additions & 6 deletions lib/internal/webstreams/readablestream.js
Expand Up @@ -54,6 +54,7 @@ const {
isArrayBufferDetached,
kEmptyObject,
kEnumerableProperty,
SideEffectFreeRegExpPrototypeSymbolReplace,
} = require('internal/util');

const {
Expand Down Expand Up @@ -140,6 +141,32 @@ const kError = Symbol('kError');
const kPull = Symbol('kPull');
const kRelease = Symbol('kRelease');

let releasedError;
let releasingError;

const userModuleRegExp = /^ {4}at (?:[^/\\(]+ \()(?!node:(.+):\d+:\d+\)$).*/gm;

function lazyReadableReleasedError() {
if (releasedError) {
return releasedError;
}

releasedError = new ERR_INVALID_STATE.TypeError('Reader released');
// Avoid V8 leak and remove userland stackstrace
releasedError.stack = SideEffectFreeRegExpPrototypeSymbolReplace(userModuleRegExp, releasedError.stack, '');
return releasedError;
}

function lazyReadableReleasingError() {
if (releasingError) {
return releasingError;
}
releasingError = new ERR_INVALID_STATE.TypeError('Releasing reader');
// Avoid V8 leak and remove userland stackstrace
releasingError.stack = SideEffectFreeRegExpPrototypeSymbolReplace(userModuleRegExp, releasingError.stack, '');
return releasingError;
}
RafaelGSS marked this conversation as resolved.
Show resolved Hide resolved

const getNonWritablePropertyDescriptor = (value) => {
return {
__proto__: null,
Expand Down Expand Up @@ -2029,7 +2056,7 @@ function readableStreamDefaultReaderRelease(reader) {
readableStreamReaderGenericRelease(reader);
readableStreamDefaultReaderErrorReadRequests(
reader,
new ERR_INVALID_STATE.TypeError('Releasing reader')
lazyReadableReleasingError(),
);
}

Expand All @@ -2044,7 +2071,7 @@ function readableStreamBYOBReaderRelease(reader) {
readableStreamReaderGenericRelease(reader);
readableStreamBYOBReaderErrorReadIntoRequests(
reader,
new ERR_INVALID_STATE.TypeError('Releasing reader')
lazyReadableReleasingError(),
);
}

Expand All @@ -2062,13 +2089,12 @@ function readableStreamReaderGenericRelease(reader) {
assert(stream !== undefined);
assert(stream[kState].reader === reader);

const releasedStateError = lazyReadableReleasedError();
if (stream[kState].state === 'readable') {
reader[kState].close.reject?.(
new ERR_INVALID_STATE.TypeError('Reader released'));
reader[kState].close.reject?.(releasedStateError);
} else {
reader[kState].close = {
promise: PromiseReject(
new ERR_INVALID_STATE.TypeError('Reader released')),
promise: PromiseReject(releasedStateError),
resolve: undefined,
reject: undefined,
};
Expand Down
22 changes: 18 additions & 4 deletions lib/internal/webstreams/writablestream.js
Expand Up @@ -34,6 +34,7 @@ const {
createDeferredPromise,
customInspectSymbol: kInspect,
kEnumerableProperty,
SideEffectFreeRegExpPrototypeSymbolReplace,
} = require('internal/util');

const {
Expand Down Expand Up @@ -77,6 +78,20 @@ const kAbort = Symbol('kAbort');
const kCloseSentinel = Symbol('kCloseSentinel');
const kError = Symbol('kError');

let releasedError;

function lazyWritableReleasedError() {
if (releasedError) {
return releasedError;
}
const userModuleRegExp = /^ {4}at (?:[^/\\(]+ \()(?!node:(.+):\d+:\d+\)$).*/gm;

releasedError = new ERR_INVALID_STATE.TypeError('Writer has been released');
// Avoid V8 leak and remove userland stackstrace
releasedError.stack = SideEffectFreeRegExpPrototypeSymbolReplace(userModuleRegExp, releasedError.stack, '');
return releasedError;
}

const getNonWritablePropertyDescriptor = (value) => {
return {
__proto__: null,
Expand Down Expand Up @@ -970,10 +985,9 @@ function writableStreamDefaultWriterRelease(writer) {
} = writer[kState];
assert(stream !== undefined);
assert(stream[kState].writer === writer);
const releasedError =
new ERR_INVALID_STATE.TypeError('Writer has been released');
writableStreamDefaultWriterEnsureReadyPromiseRejected(writer, releasedError);
writableStreamDefaultWriterEnsureClosedPromiseRejected(writer, releasedError);
const releasedStateError = lazyWritableReleasedError();
writableStreamDefaultWriterEnsureReadyPromiseRejected(writer, releasedStateError);
writableStreamDefaultWriterEnsureClosedPromiseRejected(writer, releasedStateError);
stream[kState].writer = undefined;
writer[kState].stream = undefined;
}
Expand Down