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) => {
process.nextTick(emitCloseNT, this);
if (!cb && err) {
process.nextTick(emitErrorNT, this, err);
process.nextTick(emitErrorAndCloseNT, this, err);
if (this._writableState) {
this._writableState.errorEmitted = true;
}
} else if (cb) {
process.nextTick(emitCloseNT, this);
cb(err);
} else {
process.nextTick(emitCloseNT, this);
}
});
return this;
}
function emitErrorAndCloseNT(self, err) {
emitErrorNT(self, err);
emitCloseNT(self);
}
function emitCloseNT(self) {
if (self._writableState && !self._writableState.emitClose)
return;

View File

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