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

doc: AsyncGenerator + Writable + unhandled exception #29397

Closed
ronag opened this issue Sep 1, 2019 · 5 comments
Closed

doc: AsyncGenerator + Writable + unhandled exception #29397

ronag opened this issue Sep 1, 2019 · 5 comments
Labels
doc Issues and PRs related to the documentations. good first issue Issues that are suitable for first-time contributors. stream Issues and PRs related to the stream subsystem.

Comments

@ronag
Copy link
Member

ronag commented Sep 1, 2019

Given the examples of using async generators with writable streams https://nodejs.org/dist/latest-v12.x/docs/api/stream.html#stream_piping_to_writable_streams_from_async_iterators.

There seems to be an issue in that they can cause an unhandled exception if 'error' is emitted after 'finish' (which is currently possible in some cases even with core streams). once will release the 'error' handler on completion ('finish'). I would personally discourage using it as in the example, i.e.

I would replace:

UNSAFE

const { once } = require('events');

const writable = fs.createWriteStream('./file');

(async function() {
  const readable = Readable.from(iterator);
  readable.pipe(writable);
  // Ensure completion without errors.
  await once(writable, 'finish');
})();

with

SAFE

const finished = util.promisify(stream.finished);

const writable = fs.createWriteStream('./file');

(async function() {
  const readable = Readable.from(iterator);
  readable.pipe(writable);
  // Ensure completion without errors.
  await finished(writable);
})();

or

const pipeline = util.promisify(stream.pipeline);

const writable = fs.createWriteStream('./file');

(async function() {
  const readable = Readable.from(iterator);
  await pipeline(readable, writable);
})();

and

UNSAFE

const { once } = require('events');

const writable = fs.createWriteStream('./file');

(async function() {
  for await (const chunk of iterator) {
    // Handle backpressure on write().
    if (!writable.write(chunk))
      await once(writable, 'drain');
  }
  writable.end();
  // Ensure completion without errors.
  await once(writable, 'finish');
})();

with

SAFE

const { once } = require('events');
const finished = util.promisify(stream.finished);

const writable = fs.createWriteStream('./file');

(async function() {
  for await (const chunk of iterator) {
    // Handle backpressure on write().
    if (!writable.write(chunk))
      await once(writable, 'drain');
  }
  writable.end();
  // Ensure completion without errors.
  await finished(writable);
})();

Possibly with a note on why once is not appropriate in this situation.

@ronag
Copy link
Member Author

ronag commented Sep 1, 2019

@mcollina Want a PR?

@Fishrock123 Fishrock123 added doc Issues and PRs related to the documentations. stream Issues and PRs related to the stream subsystem. good first issue Issues that are suitable for first-time contributors. labels Sep 1, 2019
@Fishrock123
Copy link
Member

@ronag Please, either that or let someone new take it.

@ronag
Copy link
Member Author

ronag commented Sep 1, 2019

let someone new take it.

+1

@mcollina
Copy link
Member

mcollina commented Sep 2, 2019

+1 on a PR.

@ckarande
Copy link
Contributor

ckarande commented Sep 2, 2019

I'd like to work on this. I will create a PR with required updates to the doc.

ckarande added a commit to ckarande/node that referenced this issue Sep 3, 2019
Update writable stream code example using async iterator to use safer
`finished()` method instead of a `finish` event to avoid uncaught
exceptions

Fixes: nodejs#29397
@Trott Trott closed this as completed in 02f3dd2 Sep 6, 2019
targos pushed a commit that referenced this issue Sep 20, 2019
Update writable stream code example using async iterator to use safer
`finished()` method instead of a `finish` event to avoid uncaught
exceptions

Fixes: #29397

PR-URL: #29425
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc Issues and PRs related to the documentations. good first issue Issues that are suitable for first-time contributors. stream Issues and PRs related to the stream subsystem.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants