Skip to content

pipeline leaves a hanging error handler #35452

Description

@szmarczak
  • Version: 14.12.0
  • Platform: Linux SZM-DESKTOP 4.19.104-microsoft-standard #1 SMP Wed Feb 19 06:37:35 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
  • Subsystem: stream

What steps will reproduce the bug?

const {pipeline, Duplex, PassThrough} = require('stream');

const a = new PassThrough();
a.end('foobar');

const b = new Duplex({
    write(chunk, encoding, callback) {
        callback();
    }
});

pipeline(a, b, error => {
    if (error) {
        throw error;
    }
    
    console.log(b.listenerCount('error'));
    setTimeout(() => {
        console.log(b.listenerCount('error'));
        b.destroy(new Error('no way'));
    }, 100);
});

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

Always.

What is the expected behavior?

0
0
[Uncaught] Error: no way

What do you see instead?

2
1

/cc @ronag

Activity

  1. ronag commented on Oct 1, 2020

    @ronag
    Member

    This is by design.

  2. ronag commented on Oct 1, 2020

    @ronag
    Member

    The docs say:

    stream.pipeline() leaves dangling event listeners on the streams after the callback has been invoked. In the case of reuse of streams after failure, this can cause event listener leaks and swallowed errors.

  3. szmarczak commented on Oct 1, 2020

    @szmarczak
    ContributorAuthor

    This is by design.

    Can this design be improved? Or is this a no?

  4. possum1102 commented on Oct 3, 2020

    @possum1102

    Hmmm

  5. deleted a comment from on Oct 3, 2020
  6. deleted a comment from on Oct 3, 2020
  7. added
    streamIssues and PRs related to Node.js streams.
    on Oct 6, 2020
  8. targos commented on Dec 13, 2020

    @targos
    Member

    /cc @nodejs/streams

  9. ronag commented on Dec 13, 2020

    @ronag
    Member

    I don’t think there is anything more to do here. Unless someone has suggestion?

  10. vweevers commented on Dec 13, 2020

    @vweevers
    Contributor

    @ronag I agree. Using pipeline() means letting pipeline() manage the lifetime of the streams, after which the streams are destroyed and should not be touched anymore.

  11. szmarczak commented on Dec 13, 2020

    @szmarczak
    ContributorAuthor

    Using pipeline() means letting pipeline() manage the lifetime of the streams

    It does not. b.destroyed is false. So the readable side is still open. The fix is either to remove the hanging handler or destroy the end stream.

  12. vweevers commented on Dec 13, 2020

    @vweevers
    Contributor

    I missed that the last stream in the example is a duplex stream. Not sure how that should behave, because the readable side can't be consumed.

  13. szmarczak commented on Dec 13, 2020

    @szmarczak
    ContributorAuthor

    the readable side can't be consumed.

    What do you mean?

  14. vweevers commented on Dec 13, 2020

    @vweevers
    Contributor

    If it were pipeline(readableStream, duplexStream, writableStream) then the readable side of duplexStream would be piped into writableStream. But if duplexStream is the last stream in the pipeline, then no one is reading from it.

    If we swap the duplex stream in your example for a writable stream, then it does get destroyed:

    const {pipeline, PassThrough, Writable} = require('stream')
    
    const a = new PassThrough()
    a.end('foobar')
    
    const b = new Writable({
      write (chunk, encoding, callback) {
        callback()
      }
    })
    
    pipeline(a, b, function (err) {
      if (err) {
        throw err
      }
    
      console.log(a.destroyed) // true
      console.log(b.destroyed) // true
    })
  15. szmarczak commented on Dec 13, 2020

    @szmarczak
    ContributorAuthor

    But if duplexStream is the last stream in the pipeline, then no one is reading from it.

    You don't know. It's readable so it's not destroyed. Something can be reading it a tick later.

  16. 3 remaining items

  17. szmarczak commented on Dec 14, 2020

    @szmarczak
    ContributorAuthor

    Sure, would love to.

  18. mcollina commented on Apr 22, 2021

    @mcollina
    SponsorMember

    @szmarczak any updates here?

  19. szmarczak commented on Apr 22, 2021

    @szmarczak
    ContributorAuthor

    Sorry, totally forgot about this one. Will sketch something in a few hours.

  20. joaoofreitas commented on Apr 22, 2021

    @joaoofreitas

    Sorry, totally forgot about this one. Will sketch something in a few hours.

    Count on me to help! @szmarczak

  21. szmarczak commented on Apr 22, 2021

    @szmarczak
    ContributorAuthor

    @joaoofreitas awesome! Feel free to send a PR first and I'll chime in and let you know my thoughts :D

  22. lvndry commented on Jul 8, 2021

    @lvndry

    If this is still work in progress I'd be happy to help

  23. mcollina commented on Jul 8, 2021

    @mcollina
    SponsorMember

    Sure thing!

  24. Heikrana commented on Feb 1, 2022

    @Heikrana

    Hey @mcollina. Can I help in this? (If @lvndry isn't working on it anymore)

    I'm new to NodeJS and to Open Source. Might be hard for me, but I'd like to try.

  25. mcollina commented on Feb 2, 2022

    @mcollina
    SponsorMember

    @Heikrana this might end up a bit too hard. Maybe try something easier first? It's one of the hardest part of Node.

  26. Heikrana commented on Feb 2, 2022

    @Heikrana

    @Heikrana this might end up a bit too hard. Maybe try something easier first? It's one of the hardest part of Node.

    Okay, I see your point. I've been trying to understand the stream API and yeah, it's a bit confusing.
    I'd still try to solve this issue (since no one else is working on it).

    But in the meantime, can you suggest me some resources (which would help me contribute to NodeJS) or another issue which might be more of my level. I really want to be part of this community :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueIssues that are suitable for first-time contributors.streamIssues and PRs related to Node.js streams.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions