Repository navigation
Writable is destroyed before calling callback in rare case #40377
Description
Activity
- changed the title
[-]Writable is destroyed before calling callback[/-][+]Writable is destroyed before calling callback in rare case[/+]on Oct 8, 2021 - addedstreamIssues and PRs related to Node.js streams.Issues and PRs related to Node.js streams.linuxIssues and PRs related to the Linux platform.Issues and PRs related to the Linux platform.
on Oct 8, 2021 @nodejs/streams
Don’t mix thenable with callback.
The behavior is correct for me. After .destroy() is called, the stream is closed synchronously and no more read or write operation can happen. However the destroy cycle is asynchronous because it might take a while to completely clean up a native resource.
@mcollina I forgot to include
Error: oh no!in expected behavior. The error is not emitted. The issue is that if_destroyreturns a thenable, there's a race condition - either the callback gets called first or the promise resolves. If it waits for the thenable, it should omit thecallbackargument (or throw when it gets called). Also the documentation doesn't mention anything about_destroybeing thenable. Therefore I consider this a bug.Uh? Using a thenable there should not be supported.
I think this is a case of insufficient documentation.
I have a feeling I missed something when we added thenable support to destroy.
I'll need to dig into this and check out what's the problem.
This was added in 744a284 without documentation.
The error is not printed because it is not rethrown by the _destroy function. Moreover, the callback should not be mixed with async/await (nor is needed).
Reacted by Szymon MarczakI think we could maybe emit a warning if function returns a thenable when the function.length has the value for the callback signature.
Reacted by Szymon MarczakWouldn't it be better to throw after the promise resolves and the callback gets called?
Wouldn't it be better to throw after the promise resolves and the callback gets called?
if you implement _destroy(), you need to rethrow or call the callback with the error passed as an argument.
Again there's this situation where callback may be called after the promise resolves. Currently calling the callback doesn't do anything because at that point the stream is destroyed already because the promise resolved.
One can expect
callbacknot to throw, so indeed a warning would be sufficient I think.- addeddocIssues and PRs related to Node.js documentation.Issues and PRs related to Node.js documentation.confirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.
on Oct 11, 2021 The documentation must be updated to better specify all of this. I would recommend to add a warning as well when using a promise with a callback.
Reacted by Szymon Marczak and Brian McDaniel- addedgood first issueIssues that are suitable for first-time contributors.Issues that are suitable for first-time contributors.
on Oct 11, 2021 I think this is a good first issue.
Version
v16.10.0
Platform
Linux solus 5.14.7-198.current #1 SMP PREEMPT Wed Sep 22 16:02:46 UTC 2021 x86_64 GNU/LinuxSubsystem
stream
What steps will reproduce the bug?
How often does it reproduce? Is there a required condition?
Always.
What is the expected behavior?
What do you see instead?
Additional information
Some undocumented behavior here:
node/lib/internal/streams/destroy.js
Lines 101 to 118 in aff2a0a