How often does it reproduce? Is there a required condition?
Always
What is the expected behavior?
.writable should be false on destroy
What do you see instead?
.writable is always true
Additional information
Since with v14+, streams no longer output errors when destroyed/ended, you need to check before piping to them. On any other stream (eg: Http2, Transform, Passthrough, Writable), you can check with .writable. This doesn't work on Http1 ServerResponse objects.
Normally, this code point is used to check if writable:
It would require special steps to see if we are piping / writing to an Http1 ServerResponse and then handle differently, or just abandoning .writable eg:
Unfortunately ServerResponse is not a real stream and not entirely consistent. We've tried to fix this, but unfortunately it breaks the ecosystem. Maybe we can do another take on it @mcollina?
streams no longer output errors when destroyed/ended, you need to check before piping to them
Not sure what you mean here? You don't need to check anything if you us pipeline.
'm not sure how to safely check again errored, but I'd assume it would always signal destroyed.
Not sure what you mean here? You don't need to check anything if you us pipeline.
Not needed for pipeline. It is needed for .pipe because unwritable streams can't emit 'end' or 'error'. I used to do something like this (simplified), because I was sometimes streaming chunks from a CDN, or piping it.
if(!destination.writable)returnfalse;// Guard against `.pipe` leaktry{if(sourceinstanceofReadable){destination.on('close', ...);destination.on('end', ...);source.pipe(destination);}else{destination.write(source);}}catch(e){returnfalse};returntrue;
If destination is ServerResponse (http1), source would never be consumed and never be released and garbage collected, causing a leak. Small because I mostly have HTTPS/HTTP2 traffic, but it happens. The try/catch probably isn't needed after v14 since ERR_STREAM_DESTROYED no longer throws on write. Not 100% sure. But, I have to replace the first line, I believe, with this:
Version
v14.19.1 / v16.14.2
Platform
Linux ROGLaptop 5.10.102.1-microsoft-standard-WSL2 #1 SMP Wed Mar 2 00:30:59 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Subsystem
http
What steps will reproduce the bug?
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior?
.writableshould befalseon destroyWhat do you see instead?
.writableis alwaystrueAdditional information
Since with v14+, streams no longer output errors when destroyed/ended, you need to check before piping to them. On any other stream (eg: Http2, Transform, Passthrough, Writable), you can check with
.writable. This doesn't work on Http1ServerResponseobjects.Normally, this code point is used to check if writable:
node/lib/internal/streams/writable.js
Lines 808 to 809 in d58f408
Instead, it's always true:
node/lib/_http_outgoing.js
Line 110 in d58f408
It would require special steps to see if we are piping / writing to an Http1
ServerResponseand then handle differently, or just abandoning.writableeg:I'm not sure how to safely check again
errored, but I'd assume it would always signal destroyed.The text was updated successfully, but these errors were encountered: