Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1717,6 +1717,11 @@ instance.setEncoding('utf8');
An attempt was made to call [`stream.write()`][] after `stream.end()` has been
called.

<a id="ERR_REQUEST_WRITE_AFTER_RESPONSE"></a>
### ERR_REQUEST_WRITE_AFTER_RESPONSE

An attempt was made to call [`req.write()`][] after `'response'` has been emitted.

<a id="ERR_STRING_TOO_LONG"></a>
### ERR_STRING_TOO_LONG

Expand Down
19 changes: 18 additions & 1 deletion lib/_http_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ const {
ERR_INVALID_ARG_TYPE,
ERR_INVALID_HTTP_TOKEN,
ERR_INVALID_PROTOCOL,
ERR_UNESCAPED_CHARACTERS
ERR_UNESCAPED_CHARACTERS,
ERR_REQUEST_WRITE_AFTER_RESPONSE
} = codes;
const { getTimerDuration } = require('internal/timers');
const {
Expand Down Expand Up @@ -302,6 +303,22 @@ ClientRequest.prototype._finish = function _finish() {
OutgoingMessage.prototype._finish.call(this);
};

ClientRequest.prototype.write = function write(chunk, encoding, callback) {
if (this.res) {
this.emit('error', new ERR_REQUEST_WRITE_AFTER_RESPONSE());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will allow the 'error' event to be emitted multiple times, are there other case where this can happen?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alternative would be worse though (throwing outside) no?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm not wrong the original ECONNRESET is forwarded to the ClientRequest instance.

return true;
}
OutgoingMessage.prototype.write.call(this, chunk, encoding, callback);
};

ClientRequest.prototype.end = function end(chunk, encoding, callback) {
if (this.res) {
this.emit('error', new ERR_REQUEST_WRITE_AFTER_RESPONSE());
return this;
}
OutgoingMessage.prototype.end.call(this, chunk, encoding, callback);
};

ClientRequest.prototype._implicitHeader = function _implicitHeader() {
if (this._header) {
throw new ERR_HTTP_HEADERS_SENT('render');
Expand Down
1 change: 1 addition & 0 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,7 @@ E('ERR_OUT_OF_RANGE',
msg += ` It must be ${range}. Received ${received}`;
return msg;
}, RangeError);
E('ERR_REQUEST_WRITE_AFTER_RESPONSE', 'write after response', Error);
E('ERR_REQUIRE_ESM', 'Must use import to load ES Module: %s', Error);
E('ERR_SCRIPT_EXECUTION_INTERRUPTED',
'Script execution was interrupted by `SIGINT`', Error);
Expand Down