-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
lib: reuse invalid state errors on webstreams #46086
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the stack trace of this error? Make sure it does should not include any user lines.
I can remove the UPDATE: I've updated to use |
97dff7d
to
4540f14
Compare
what's the final stack trace for these then? What's t.js in your stacktrace above? |
4540f14
to
9f94cb9
Compare
Stacktrace rafaelgss@rafaelgss-desktop:~/repos/os/node$ ./node t.js
node:internal/errors:490
ErrorCaptureStackTrace(err);
^
TypeError [ERR_INVALID_STATE]: Invalid state: Reader released
at readableStreamReaderGenericRelease (node:internal/webstreams/readablestream:2079:30)
at readableStreamDefaultReaderRelease (node:internal/webstreams/readablestream:2043:3)
at ReadableStreamDefaultReader.releaseLock (node:internal/webstreams/readablestream:833:5)
at main (/home/rafaelgss/repos/os/node/t.js:13:10) {
code: 'ERR_INVALID_STATE'
}
Node.js v20.0.0-pre
const { ReadableStream } = require('node:stream/web')
async function main() {
const stream = new ReadableStream({
start(controller) {
controller.close();
},
});
const reader = stream.getReader();
await reader.closed;
reader.releaseLock(); // the error is created here
await reader.closed; // this should throw the invalid state error
}
main() |
Unfortunately, you'd need to remove everything that's not internal, otherwise users could be utterly confused. |
9f94cb9
to
42c40ed
Compare
@mcollina What about it now?
|
releasedError = new ERR_INVALID_STATE.TypeError('Reader released'); | ||
// Avoid V8 leak and remove userland stackstrace | ||
releasedError.stack = SideEffectFreeRegExpPrototypeSymbolReplace( | ||
/^.*\((?!node:|internal)[^()]*\).*$/gm, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good start but it won't match all internal frames. There are e.g., not always brackets involved.
The best one to match I could come up with was: const coreModuleRegExp = /^ {4}at (?:[^/\\(]+ \(|)node:(.+):\d+:\d+\)?$/;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I've changed it a bit to perform the inverse operation (userland modules). Can you double-check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com>
42c40ed
to
4c65282
Compare
Landed in 5d50b84 |
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com> PR-URL: nodejs#46086 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com> PR-URL: nodejs#46086 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com> PR-URL: nodejs#46086 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com> PR-URL: nodejs#46086 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com> PR-URL: #46086 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com> PR-URL: #46086 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com> PR-URL: #46086 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
We are tracking internally the webstreams performance and after some investigation (nodejs/undici#1203, nodejs/performance#9 (comment)), we found that one of the bottlenecks is the
NodeError
creation.undici.fetch
as a real use case of web streams, the benchmark files are available at https://github.com/RafaelGSS/nodejs-webstreams-perf/blob/main/bench/fetch.jsundici.fetch
performance by approximately 23%.I'm not quite sure about the security impacts of this change, considering we're going to use the same object for all release calls.
More information on this performance work can be found at nodejs/performance#9.