stream: always emit error before close

PR-URL: https://github.com/nodejs/node/pull/19836
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
Mathias Buus 2018-04-05 20:52:19 +02:00
parent 0cd8359652
commit a7c25b7d42
3 changed files with 37 additions and 6 deletions

View File

@ -30,20 +30,27 @@ function destroy(err, cb) {
} }
this._destroy(err || null, (err) => { this._destroy(err || null, (err) => {
process.nextTick(emitCloseNT, this);
if (!cb && err) { if (!cb && err) {
process.nextTick(emitErrorNT, this, err); process.nextTick(emitErrorAndCloseNT, this, err);
if (this._writableState) { if (this._writableState) {
this._writableState.errorEmitted = true; this._writableState.errorEmitted = true;
} }
} else if (cb) { } else if (cb) {
process.nextTick(emitCloseNT, this);
cb(err); cb(err);
} else {
process.nextTick(emitCloseNT, this);
} }
}); });
return this; return this;
} }
function emitErrorAndCloseNT(self, err) {
emitErrorNT(self, err);
emitCloseNT(self);
}
function emitCloseNT(self) { function emitCloseNT(self) {
if (self._writableState && !self._writableState.emitClose) if (self._writableState && !self._writableState.emitClose)
return; return;

View File

@ -9,8 +9,8 @@ let client;
let req; let req;
const server = http2.createServer(); const server = http2.createServer();
server.on('stream', common.mustCall((stream) => { server.on('stream', common.mustCall((stream) => {
stream.on('close', common.mustCall(() => {
stream.on('error', common.mustCall(() => { stream.on('error', common.mustCall(() => {
stream.on('close', common.mustCall(() => {
server.close(); server.close();
})); }));
})); }));
@ -21,8 +21,8 @@ server.listen(0, common.mustCall(() => {
client = http2.connect(`http://localhost:${server.address().port}`); client = http2.connect(`http://localhost:${server.address().port}`);
req = client.request(); req = client.request();
req.resume(); req.resume();
req.on('close', common.mustCall(() => {
req.on('error', common.mustCall(() => { req.on('error', common.mustCall(() => {
req.on('close', common.mustCall(() => {
client.close(); client.close();
})); }));
})); }));

View File

@ -0,0 +1,24 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const { Readable } = require('stream');
const rs = new Readable({
read() {}
});
let closed = false;
let errored = false;
rs.on('close', common.mustCall(() => {
closed = true;
assert(errored);
}));
rs.on('error', common.mustCall((err) => {
errored = true;
assert(!closed);
}));
rs.destroy(new Error('kaboom'));