mirror of
https://github.com/nodejs/node.git
synced 2026-10-28 10:15:07 +08:00
stream: reject closed only after sink abort settles
Signed-off-by: Lazizbek Ergashev <lazerg2@gmail.com> PR-URL: https://github.com/nodejs/node/pull/65727 Fixes: https://github.com/nodejs/node/issues/65726 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
This commit is contained in:
1 parent
1278496599
commit
50b355ec04
2 files changed
+49
No files matched your search
@@ -928,6 +928,13 @@ function writableStreamFinishErroring(stream) {
|
||||
writableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
|
||||
return;
|
||||
}
|
||||
// The closed promises are only rejected once the sink's abort algorithm
|
||||
// settles, so materialize them here: deriving them from the 'errored'
|
||||
// state within that window would hand out an already rejected promise.
|
||||
stream[kState].closedPromise ??= PromiseWithResolvers();
|
||||
const writer = stream[kState].writer;
|
||||
if (writer !== undefined)
|
||||
writer[kState].close ??= PromiseWithResolvers();
|
||||
PromisePrototypeThen(
|
||||
stream[kState].controller[kAbort](abortRequest.reason),
|
||||
() => {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
'use strict';
|
||||
|
||||
// The writer's closed promise stays pending until the sink's abort()
|
||||
// algorithm settles, even when it is first observed after the stream has
|
||||
// already reached the 'errored' state.
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const { setImmediate: immediate } = require('timers/promises');
|
||||
const { WritableStream } = require('stream/web');
|
||||
|
||||
async function main() {
|
||||
const error = new Error('boom');
|
||||
const { promise: abortComplete, resolve: finishAbort } = Promise.withResolvers();
|
||||
const ws = new WritableStream({
|
||||
abort: common.mustCall((reason) => {
|
||||
assert.strictEqual(reason, error);
|
||||
return abortComplete;
|
||||
}),
|
||||
});
|
||||
const writer = ws.getWriter();
|
||||
const aborted = writer.abort(error);
|
||||
|
||||
// Lets the stream finish erroring and call the sink's abort().
|
||||
await immediate();
|
||||
|
||||
let closedSettled = false;
|
||||
const closed = writer.closed.catch(common.mustCall((reason) => {
|
||||
closedSettled = true;
|
||||
assert.strictEqual(reason, error);
|
||||
}));
|
||||
|
||||
await immediate();
|
||||
assert.strictEqual(closedSettled, false);
|
||||
|
||||
finishAbort();
|
||||
await aborted;
|
||||
await closed;
|
||||
assert.strictEqual(closedSettled, true);
|
||||
}
|
||||
|
||||
main().then(common.mustCall());
|
||||
Reference in new issue
Block a user