Uh oh!
There was an error while loading. Please reload this page.
stream: do not swallow errors with async iterators and pipeline - #32051
stream: do not swallow errors with async iterators and pipeline#32051mcollina wants to merge 2 commits into
Conversation
nodejs-github-bot
commented
Mar 2, 2020
Something else is going on here. I don't understand how this can cause premature close. It seems that the The test can be further simplified to: {constrs=newReadable({read(){setImmediate(()=>{rs.push('hello');});}});pipeline(rs,asyncfunction*(stream){/* eslint no-unused-vars: off */forawait(constchunkofstream){thrownewError('kaboom');}},common.mustCall((err)=>{assert.strictEqual(err.message,'kaboom');}));}EDIT: The throw inside the iterable seems to call iterator.return instead of iterator.throw which I find strange, but maybe that's the way it's supposed to work? forawait(constchunkofstream){thrownewError('kaboom');}this will call |
mcollina
commented
Mar 2, 2020
I thought the same as well, and I do not understand why the catch call is never reached. I was not be able to reproduce the problem with just our async iterator code. The “bug” comes from the interaction between all the streams and the async iterator. Not that for an async iterator in pipeline we have 3 finished() calls that gets into play (1 in the main async iterator, 1 inside the finish function called from return, and one inside pipeline). The internal error is swallowed because the iterator ends abruptly and it causes the other streams to close. Those premature closes are forwarded earlier than the error from the internal async iterator. At least, that’s my read of the problem. Let me know if you can crack this :/. |
mcollina
commented
Mar 2, 2020
That’s what I discovered as well. I think it’s how it works. |
Uh oh!
There was an error while loading. Please reload this page.
ronag
commented
Mar 2, 2020
Sorry, the close was a misclick. I don't like this solution but I can't really think of anything better...
If this is not an urgent issue please give me a few days to try to crack it before landing this. |
devsnek
commented
Mar 2, 2020
I can confirm this is the correct behaviour (I have absolutely no idea why though, I'd have to dig into old tc39 notes) |
@devsnek Do you have any advice here? We had a short mail conversation in regards to a related topic some time ago. In particular, I'm curious why the iterator protocol would not call EDIT: wow, nice timing @devsnek |
devsnek
commented
Mar 3, 2020
Ok this is basically a difference in the node stream model and the async iterator model. In node.js, the streams own errors that happen while they are being consumed ( |
bakkot
commented
Mar 3, 2020
To expand a bit: My mental model of |
6ac2f87 to
89b2368Comparemcollina
commented
Mar 3, 2020
@ronag this should be a better fix. The problem we were facing was a race between the ERR_STREAM_PREMATURE_CLOSE of the last stream and the error produced by the async iteration. I've solved the bug by having the callback called when all streams have been successfully destroyed and just not the last. |
ronag
left a comment
There was a problem hiding this comment.
Nice! A few questions though.
Why not just set finishCount to the number of calls to wrap? That way you only need to decrement it in the destroyer callback.
Uh oh!
There was an error while loading. Please reload this page.
77019be to
4d34ee6CompareBefore this patch, pipeline() could swallow errors by pre-emptively producing a ERR_STREAM_PREMATURE_CLOSE that was not really helpful to the user. Co-Authored-By: Robert Nagy <ronagy@icloud.com>
4d34ee6 to
e4c3f55Comparemcollina
commented
Mar 9, 2020
it changed too much since last review, PTAL.
mcollina
commented
Mar 9, 2020
nodejs-github-bot
commented
Mar 9, 2020
Uh oh!
There was an error while loading. Please reload this page.
nodejs-github-bot
commented
Mar 10, 2020
nodejs-github-bot
commented
Mar 11, 2020
Before this patch, pipeline() could swallow errors by pre-emptively producing a ERR_STREAM_PREMATURE_CLOSE that was not really helpful to the user. Co-Authored-By: Robert Nagy <ronagy@icloud.com> PR-URL: #32051 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
mcollina
commented
Mar 11, 2020
Landed as d7fe554 |
Before this patch, pipeline() could swallow errors by pre-emptively producing a ERR_STREAM_PREMATURE_CLOSE that was not really helpful to the user. Co-Authored-By: Robert Nagy <ronagy@icloud.com> PR-URL: #32051 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Before this patch, pipeline() could swallow errors by pre-emptively
producing a ERR_STREAM_PREMATURE_CLOSE that was not really helpful
to the user.
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passes