Skip to content

Commit 42c40ed

Browse files
committed
lib: reuse invalid state errors on webstreams
Signed-off-by: RafaelGSS <[email protected]>
1 parent a03529d commit 42c40ed

File tree

2 files changed

+52
-10
lines changed

2 files changed

+52
-10
lines changed

lib/internal/webstreams/readablestream.js

+33-6
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const {
5454
isArrayBufferDetached,
5555
kEmptyObject,
5656
kEnumerableProperty,
57+
SideEffectFreeRegExpPrototypeSymbolReplace,
5758
} = require('internal/util');
5859

5960
const {
@@ -140,6 +141,33 @@ const kError = Symbol('kError');
140141
const kPull = Symbol('kPull');
141142
const kRelease = Symbol('kRelease');
142143

144+
let releasedError;
145+
let releasingError;
146+
147+
function lazyReadableReleasedError() {
148+
if (releasedError) {
149+
return releasedError;
150+
}
151+
releasedError = new ERR_INVALID_STATE.TypeError('Reader released');
152+
// Avoid V8 leak and remove userland stackstrace
153+
releasedError.stack = SideEffectFreeRegExpPrototypeSymbolReplace(
154+
/^.*\((?!node:|internal)[^()]*\).*$/gm,
155+
releasedError.stack, '');
156+
return releasedError;
157+
}
158+
159+
function lazyReadableReleasingError() {
160+
if (releasingError) {
161+
return releasingError;
162+
}
163+
releasingError = new ERR_INVALID_STATE.TypeError('Releasing reader');
164+
// Avoid V8 leak and remove userland stackstrace
165+
releasingError.stack = SideEffectFreeRegExpPrototypeSymbolReplace(
166+
/^.*\((?!node:|internal)[^()]*\).*$/gm,
167+
releasingError.stack, '');
168+
return releasingError;
169+
}
170+
143171
const getNonWritablePropertyDescriptor = (value) => {
144172
return {
145173
__proto__: null,
@@ -2029,7 +2057,7 @@ function readableStreamDefaultReaderRelease(reader) {
20292057
readableStreamReaderGenericRelease(reader);
20302058
readableStreamDefaultReaderErrorReadRequests(
20312059
reader,
2032-
new ERR_INVALID_STATE.TypeError('Releasing reader')
2060+
lazyReadableReleasingError(),
20332061
);
20342062
}
20352063

@@ -2044,7 +2072,7 @@ function readableStreamBYOBReaderRelease(reader) {
20442072
readableStreamReaderGenericRelease(reader);
20452073
readableStreamBYOBReaderErrorReadIntoRequests(
20462074
reader,
2047-
new ERR_INVALID_STATE.TypeError('Releasing reader')
2075+
lazyReadableReleasingError(),
20482076
);
20492077
}
20502078

@@ -2062,13 +2090,12 @@ function readableStreamReaderGenericRelease(reader) {
20622090
assert(stream !== undefined);
20632091
assert(stream[kState].reader === reader);
20642092

2093+
const releasedStateError = lazyReadableReleasedError();
20652094
if (stream[kState].state === 'readable') {
2066-
reader[kState].close.reject?.(
2067-
new ERR_INVALID_STATE.TypeError('Reader released'));
2095+
reader[kState].close.reject?.(releasedStateError);
20682096
} else {
20692097
reader[kState].close = {
2070-
promise: PromiseReject(
2071-
new ERR_INVALID_STATE.TypeError('Reader released')),
2098+
promise: PromiseReject(releasedStateError),
20722099
resolve: undefined,
20732100
reject: undefined,
20742101
};

lib/internal/webstreams/writablestream.js

+19-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const {
2424
ERR_INVALID_STATE,
2525
ERR_INVALID_THIS,
2626
},
27+
hideStackFrames,
2728
} = require('internal/errors');
2829

2930
const {
@@ -34,6 +35,7 @@ const {
3435
createDeferredPromise,
3536
customInspectSymbol: kInspect,
3637
kEnumerableProperty,
38+
SideEffectFreeRegExpPrototypeSymbolReplace,
3739
} = require('internal/util');
3840

3941
const {
@@ -77,6 +79,20 @@ const kAbort = Symbol('kAbort');
7779
const kCloseSentinel = Symbol('kCloseSentinel');
7880
const kError = Symbol('kError');
7981

82+
let releasedError;
83+
84+
function lazyWritableReleasedError() {
85+
if (releasedError) {
86+
return releasedError;
87+
}
88+
releasedError = new ERR_INVALID_STATE.TypeError('Writer has been released');
89+
// Avoid V8 leak and remove userland stackstrace
90+
releasedError.stack = SideEffectFreeRegExpPrototypeSymbolReplace(
91+
/^.*\((?!node:|internal)[^()]*\).*$/gm,
92+
releasedError.stack, '');
93+
return releasedError;
94+
};
95+
8096
const getNonWritablePropertyDescriptor = (value) => {
8197
return {
8298
__proto__: null,
@@ -970,10 +986,9 @@ function writableStreamDefaultWriterRelease(writer) {
970986
} = writer[kState];
971987
assert(stream !== undefined);
972988
assert(stream[kState].writer === writer);
973-
const releasedError =
974-
new ERR_INVALID_STATE.TypeError('Writer has been released');
975-
writableStreamDefaultWriterEnsureReadyPromiseRejected(writer, releasedError);
976-
writableStreamDefaultWriterEnsureClosedPromiseRejected(writer, releasedError);
989+
const releasedStateError = lazyWritableReleasedError();
990+
writableStreamDefaultWriterEnsureReadyPromiseRejected(writer, releasedStateError);
991+
writableStreamDefaultWriterEnsureClosedPromiseRejected(writer, releasedStateError);
977992
stream[kState].writer = undefined;
978993
writer[kState].stream = undefined;
979994
}

0 commit comments

Comments
 (0)