Skip to content

Writable is destroyed before calling callback in rare case #40377

@szmarczak

Description

@szmarczak

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/Linux

Subsystem

stream

What steps will reproduce the bug?

const {Writable} = require('stream');

class X extends Writable {
    async _destroy(error, callback) {
        (async () => {
            await new Promise(resolve => setTimeout(resolve, 10));
            console.log(w._writableState.closed);

            callback(error);
        })();
    }
}

const w = new X();

w.once('error', error => {
    console.log(error);
});

w.destroy(new Error('oh no!'));

How often does it reproduce? Is there a required condition?

Always.

What is the expected behavior?

false
Error: oh no!

What do you see instead?

true

Additional information

Some undocumented behavior here:

try {
const result = self._destroy(err || null, onDestroy);
if (result != null) {
const then = result.then;
if (typeof then === 'function') {
then.call(
result,
function() {
process.nextTick(onDestroy, null);
},
function(err) {
process.nextTick(onDestroy, err);
});
}
}
} catch (err) {
onDestroy(err);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugIssues with confirmed bugs.docIssues and PRs related to the documentations.good first issueIssues that are suitable for first-time contributors.linuxIssues and PRs related to the Linux platform.streamIssues and PRs related to the stream subsystem.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions