From 334d4f6256541f37b1328d66edf4c068b92c012a Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Fri, 20 Sep 2019 18:19:35 +0200 Subject: [PATCH] http: add captureRejection support to OutgoingMessage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/27867 Reviewed-By: Benjamin Gruenbaum Reviewed-By: James M Snell Reviewed-By: Jeremiah Senkpiel Reviewed-By: Anna Henningsen Reviewed-By: Michaƫl Zasso --- lib/_http_outgoing.js | 6 ++ ...http-outgoing-message-capture-rejection.js | 89 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 test/parallel/test-http-outgoing-message-capture-rejection.js diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index e331d073b57067..c3bfbd09bfca0c 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -32,6 +32,7 @@ const { const { getDefaultHighWaterMark } = require('internal/streams/state'); const assert = require('internal/assert'); +const EE = require('events'); const Stream = require('stream'); const internalUtil = require('internal/util'); const { kOutHeaders, utcDate, kNeedDrain } = require('internal/http'); @@ -884,6 +885,11 @@ OutgoingMessage.prototype.pipe = function pipe() { this.emit('error', new ERR_STREAM_CANNOT_PIPE()); }; +OutgoingMessage.prototype[EE.captureRejectionSymbol] = +function(err, event) { + this.destroy(err); +}; + module.exports = { OutgoingMessage }; diff --git a/test/parallel/test-http-outgoing-message-capture-rejection.js b/test/parallel/test-http-outgoing-message-capture-rejection.js new file mode 100644 index 00000000000000..5f667ea17ea156 --- /dev/null +++ b/test/parallel/test-http-outgoing-message-capture-rejection.js @@ -0,0 +1,89 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const events = require('events'); +const { createServer, request } = require('http'); + +events.captureRejections = true; + +{ + const server = createServer(common.mustCall((req, res) => { + const _err = new Error('kaboom'); + res.on('drain', common.mustCall(async () => { + throw _err; + })); + + res.socket.on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + })); + + // Write until there is space in the buffer + while (res.write('hello')) {} + })); + + server.listen(0, common.mustCall(() => { + const req = request({ + method: 'GET', + host: server.address().host, + port: server.address().port + }); + + req.end(); + + req.on('response', common.mustCall((res) => { + res.on('aborted', common.mustCall()); + res.resume(); + server.close(); + })); + })); +} + +{ + let _res; + let shouldEnd = false; + // Not using mustCall here, because it is OS-dependant. + const server = createServer((req, res) => { + // So that we cleanly stop + _res = res; + + if (shouldEnd) { + res.end(); + } + }); + + server.listen(0, common.mustCall(() => { + const _err = new Error('kaboom'); + + const req = request({ + method: 'POST', + host: server.address().host, + port: server.address().port + }); + + req.on('response', common.mustNotCall((res) => { + // So that we cleanly stop + res.resume(); + server.close(); + })); + + req.on('error', common.mustCall((err) => { + server.close(); + // On some variants of Windows, this can happen before + // the server has received the request. + if (_res) { + _res.end(); + } else { + shouldEnd = true; + } + assert.strictEqual(err, _err); + })); + + req.on('drain', common.mustCall(async () => { + throw _err; + })); + + // Write until there is space in the buffer + while (req.write('hello')) {} + })); +}