Skip to content

Dealing with async errors during _read() #29584

@ronag

Description

@ronag

I feel like there is something missing in the streams _read API for implementors.

Basically the current state of things is that stream implementors need to implement async error handling something like this:

_read (n) {
  doAsyncRead(n, (err, buf) => {
    if (err) {
      if (this._readableState.autoDestroy) {
        this.destroy(err)
      } else {
        this.emit('error', err)
      }
    } else {
      this.push(buf)
    }
  })
}

There are some problems with this:

  1. Most stream implementors don't do this and simply don't bother to conform to the autoDestroy option and either destroy() or emit('error', err), which one they choose is mostly unclear and undocumented.
  2. Even when conforming you either have to access the _readableState object or add a flag based on the options sent to the Readable super.

I'm not quite sure how to resolve this. I can think of a few ways:

  1. Add a cb to _read that can be invoked with an error and would internally call the errorOrDestroy method.
  2. Make the errorOrDestroy util directly accessible for stream implementors and document it somehow.
  3. Leave as is and clarify in documentation how to handle this scenario (preferable without _readableState).
  4. Deprecate autoDestroy and make it true by default.
  5. Document that autoDestroy is for stream implementors only and not for stream consumers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    streamIssues and PRs related to the stream subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions