Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stream: improve Readable.from error handling #37158

Closed

Conversation

benjamingr
Copy link
Member

This pull request aligns the behaviour of Readable.from with other stream behaviours namely:

  • Errors thrown in the stream now propagate via .throw and not via .on and reach catch blocks. This means things like addAbortSignal work with Readable.from now.
  • The generator is always closed, even if next was not called - this is because the previous implementation had a timing bug where if next was called and the stream was destroyed in the same tick - finally blocks would not run.

cc @ronag @mcollina @nodejs/streams

@benjamingr benjamingr added the stream Issues and PRs related to the stream subsystem. label Jan 31, 2021
};

async function close() {
async function close(error) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is tricky and I want feedback on the semantics, basically:

  • If we had an error ( .destroy(err) ) we call .throw - this aligns the behaviour of .from with other methods and means stuff like addAbortSignal automagically "works".
  • If after calling throw the iterator did not finish - we also call .return

if (done) {
readable.push(null);
} else if (readable.destroyed) {
await close();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is no longer necessary without needToClose since _destroy is called and if the stream is destroyed the iterator is closed.

Copy link
Member

@ronag ronag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

lib/internal/streams/from.js Outdated Show resolved Hide resolved
lib/internal/streams/from.js Outdated Show resolved Hide resolved
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

};

async function close() {
async function close(error) {
const hadError = typeof error !== 'undefined';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't error be null?

const result = self._destroy(err || null, (err) => {

@aduh95 aduh95 force-pushed the fix-async-iterator-errors branch from 3f712a5 to 0bce498 Compare February 1, 2021 14:30
@aduh95
Copy link
Contributor

aduh95 commented Feb 1, 2021

I've rebased and force pushed to solve to git conflicts introduced by my PR.

@benjamingr
Copy link
Member Author

@aduh95 very kind of you, thanks 🙇‍♂️

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@benjamingr
Copy link
Member Author

benjamingr commented Feb 2, 2021

@mcollina I might be a bit overcautious* - but I prefer to err on the side of caution.

What steps can I take to ensure there is less breakage here?

Thoughts:

Anything else?

(since the old behaviour was just an overlooked bug/edge-case and probably not relied on)

@benjamingr benjamingr added the blocked PRs that are blocked by other issues or PRs. label Feb 2, 2021
@benjamingr
Copy link
Member Author

Putting "blocked" so this doesn't land by accident in the meantime.

@benjamingr
Copy link
Member Author

I went through most CITGM failures and there don't seem to be new/related ones

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@mcollina
Copy link
Member

mcollina commented Feb 3, 2021

I do not think we have any modules using this in CITGM. It's not touching any old/critical APIs, so it should be good to land.

@mcollina mcollina removed the blocked PRs that are blocked by other issues or PRs. label Feb 3, 2021
@benjamingr
Copy link
Member Author

Thanks matteo. Landed in 03380bc

@benjamingr benjamingr closed this Feb 3, 2021
benjamingr added a commit that referenced this pull request Feb 3, 2021
PR-URL: #37158
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@benjamingr benjamingr deleted the fix-async-iterator-errors branch February 3, 2021 11:23
@benjamingr benjamingr added the semver-minor PRs that contain new features and should be released in the next minor version. label Feb 3, 2021
danielleadams pushed a commit that referenced this pull request Feb 16, 2021
PR-URL: #37158
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
danielleadams added a commit that referenced this pull request Feb 16, 2021
Notable Changes:

* crypto:
  * add keyObject.export() 'jwk' format option (Filip Skokan) #37081
* deps:
  * upgrade to libuv 1.41.0 (Colin Ihrig) #37360
* doc:
  * add dmabupt to collaborators (Xu Meng) #37377
  * refactor fs docs structure (James M Snell) #37170
* fs:
  * add fsPromises.watch() (James M Snell) #37179
  * use a default callback for fs.close() (James M Snell) #37174
  * add AbortSignal support to watch (Benjamin Gruenbaum) #37190
* perf_hooks:
  * introduce createHistogram (James M Snell) #37155
* stream:
  * improve Readable.from error handling (Benjamin Gruenbaum) #37158
* timers:
  * introduce setInterval async iterator (linkgoron) #37153
* tls:
  * add ability to get cert/peer cert as X509Certificate object (James M Snell) #37070
This was referenced Feb 16, 2021
danielleadams added a commit that referenced this pull request Feb 17, 2021
Notable Changes:

* crypto:
  * add keyObject.export() 'jwk' format option (Filip Skokan) #37081
* deps:
  * upgrade to libuv 1.41.0 (Colin Ihrig) #37360
* doc:
  * add dmabupt to collaborators (Xu Meng) #37377
  * refactor fs docs structure (James M Snell) #37170
* fs:
  * add fsPromises.watch() (James M Snell) #37179
  * use a default callback for fs.close() (James M Snell) #37174
  * add AbortSignal support to watch (Benjamin Gruenbaum) #37190
* perf_hooks:
  * introduce createHistogram (James M Snell) #37155
* stream:
  * improve Readable.from error handling (Benjamin Gruenbaum) #37158
* timers:
  * introduce setInterval async iterator (linkgoron) #37153
* tls:
  * add ability to get cert/peer cert as X509Certificate object (James M Snell) #37070
danielleadams added a commit that referenced this pull request Feb 17, 2021
Notable Changes:

* crypto:
  * add keyObject.export() jwk format option (Filip Skokan) #37081
* deps:
  * upgrade to libuv 1.41.0 (Colin Ihrig) #37360
* doc:
  * add dmabupt to collaborators (Xu Meng) #37377
  * refactor fs docs structure (James M Snell) #37170
* fs:
  * add fsPromises.watch() (James M Snell) #37179
  * use a default callback for fs.close() (James M Snell) #37174
  * add AbortSignal support to watch (Benjamin Gruenbaum) #37190
* perf_hooks:
  * introduce createHistogram (James M Snell) #37155
* stream:
  * improve Readable.from error handling (Benjamin Gruenbaum) #37158
* timers:
  * introduce setInterval async iterator (linkgoron) #37153
* tls:
  * add ability to get cert/peer cert as X509Certificate object (James M Snell) #37070
danielleadams added a commit that referenced this pull request Feb 17, 2021
PR-URL: #37406

Notable Changes:

* crypto:
  * add keyObject.export() jwk format option (Filip Skokan) #37081
* deps:
  * upgrade to libuv 1.41.0 (Colin Ihrig) #37360
* doc:
  * add dmabupt to collaborators (Xu Meng) #37377
  * refactor fs docs structure (James M Snell) #37170
* fs:
  * add fsPromises.watch() (James M Snell) #37179
  * use a default callback for fs.close() (James M Snell) #37174
  * add AbortSignal support to watch (Benjamin Gruenbaum) #37190
* perf_hooks:
  * introduce createHistogram (James M Snell) #37155
* stream:
  * improve Readable.from error handling (Benjamin Gruenbaum) #37158
* timers:
  * introduce setInterval async iterator (linkgoron) #37153
* tls:
  * add ability to get cert/peer cert as X509Certificate object (James M Snell) #37070
danielleadams added a commit that referenced this pull request Feb 18, 2021
PR-URL: #37406

Notable Changes:

* crypto:
  * add keyObject.export() jwk format option (Filip Skokan) #37081
* deps:
  * upgrade to libuv 1.41.0 (Colin Ihrig) #37360
* doc:
  * add dmabupt to collaborators (Xu Meng) #37377
  * refactor fs docs structure (James M Snell) #37170
* fs:
  * add fsPromises.watch() (James M Snell) #37179
  * use a default callback for fs.close() (James M Snell) #37174
  * add AbortSignal support to watch (Benjamin Gruenbaum) #37190
* perf_hooks:
  * introduce createHistogram (James M Snell) #37155
* stream:
  * improve Readable.from error handling (Benjamin Gruenbaum) #37158
* timers:
  * introduce setInterval async iterator (linkgoron) #37153
* tls:
  * add ability to get cert/peer cert as X509Certificate object (James M Snell) #37070
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver-minor PRs that contain new features and should be released in the next minor version. stream Issues and PRs related to the stream subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants