diff --git a/doc/api/errors.md b/doc/api/errors.md
index 23817ef3d1924f..ad34c15896d84b 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -818,9 +818,11 @@ HTTP/1 connection specific headers are forbidden to be used in HTTP/2
requests and responses.
-### ERR_HTTP2_INVALID_HEADER_VALUE
+### ERR_HTTP_INVALID_HEADER_VALUE
+
+### ERR_HTTP_INVALID_HEADER_VALUE
-Used to indicate that an invalid HTTP/2 header value has been specified.
+Used to indicate that an invalid HTTP header value has been specified.
### ERR_HTTP2_INVALID_INFO_STATUS
diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js
index 76d83b19218ceb..b5f87d604d4282 100644
--- a/lib/_http_outgoing.js
+++ b/lib/_http_outgoing.js
@@ -437,16 +437,7 @@ function _storeHeader(firstLine, headers) {
function storeHeader(self, state, key, value, validate) {
if (validate) {
- if (typeof key !== 'string' || !key || !checkIsHttpToken(key)) {
- throw new errors.TypeError(
- 'ERR_INVALID_HTTP_TOKEN', 'Header name', key);
- }
- if (value === undefined) {
- throw new errors.TypeError('ERR_MISSING_ARGS', `header "${key}"`);
- } else if (checkInvalidHeaderChar(value)) {
- debug('Header "%s" contains invalid characters', key);
- throw new errors.TypeError('ERR_INVALID_CHAR', 'header content', key);
- }
+ validateHeader(key, value);
}
state.header += key + ': ' + escapeHeaderValue(value) + CRLF;
matchHeader(self, state, key, value);
@@ -494,20 +485,27 @@ function matchHeader(self, state, field, value) {
}
}
-function validateHeader(msg, name, value) {
- if (typeof name !== 'string' || !name || !checkIsHttpToken(name))
- throw new errors.TypeError('ERR_INVALID_HTTP_TOKEN', 'Header name', name);
- if (value === undefined)
- throw new errors.TypeError('ERR_MISSING_ARGS', 'value');
- if (msg._header)
- throw new errors.Error('ERR_HTTP_HEADERS_SENT', 'set');
- if (checkInvalidHeaderChar(value)) {
+function validateHeader(name, value) {
+ var err;
+ if (typeof name !== 'string' || !name || !checkIsHttpToken(name)) {
+ err = new errors.TypeError('ERR_INVALID_HTTP_TOKEN', 'Header name', name);
+ } else if (value === undefined) {
+ err = new errors.TypeError('ERR_HTTP_INVALID_HEADER_VALUE', value, name);
+ } else if (checkInvalidHeaderChar(value)) {
debug('Header "%s" contains invalid characters', name);
- throw new errors.TypeError('ERR_INVALID_CHAR', 'header content', name);
+ err = new errors.TypeError('ERR_INVALID_CHAR', 'header content', name);
+ }
+ if (err) {
+ Error.captureStackTrace(err, validateHeader);
+ throw err;
}
}
+
OutgoingMessage.prototype.setHeader = function setHeader(name, value) {
- validateHeader(this, name, value);
+ if (this._header) {
+ throw new errors.Error('ERR_HTTP_HEADERS_SENT', 'set');
+ }
+ validateHeader(name, value);
if (!this[outHeadersKey])
this[outHeadersKey] = {};
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index 7148279672c2cc..0e7f049a0cd275 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -204,7 +204,6 @@ E('ERR_HTTP2_INFO_STATUS_NOT_ALLOWED',
'Informational status codes cannot be used');
E('ERR_HTTP2_INVALID_CONNECTION_HEADERS',
'HTTP/1 Connection specific headers are forbidden: "%s"');
-E('ERR_HTTP2_INVALID_HEADER_VALUE', 'Value must not be undefined or null');
E('ERR_HTTP2_INVALID_INFO_STATUS',
(code) => `Invalid informational status code: ${code}`);
E('ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH',
@@ -241,6 +240,7 @@ E('ERR_HTTP2_UNSUPPORTED_PROTOCOL',
E('ERR_HTTP_HEADERS_SENT',
'Cannot %s headers after they are sent to the client');
E('ERR_HTTP_INVALID_CHAR', 'Invalid character in statusMessage.');
+E('ERR_HTTP_INVALID_HEADER_VALUE', 'Invalid value "%s" for header "%s"');
E('ERR_HTTP_INVALID_STATUS_CODE',
(originalStatusCode) => `Invalid status code: ${originalStatusCode}`);
E('ERR_HTTP_TRAILER_INVALID',
diff --git a/lib/internal/http2/compat.js b/lib/internal/http2/compat.js
index c96fc931969f39..f4ce18798bee84 100644
--- a/lib/internal/http2/compat.js
+++ b/lib/internal/http2/compat.js
@@ -40,12 +40,18 @@ let statusMessageWarned = false;
// close as possible to the current require('http') API
function assertValidHeader(name, value) {
- if (name === '' || typeof name !== 'string')
- throw new errors.TypeError('ERR_INVALID_HTTP_TOKEN', 'Header name', name);
- if (isPseudoHeader(name))
- throw new errors.Error('ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED');
- if (value === undefined || value === null)
- throw new errors.TypeError('ERR_HTTP2_INVALID_HEADER_VALUE');
+ var err;
+ if (name === '' || typeof name !== 'string') {
+ err = new errors.TypeError('ERR_INVALID_HTTP_TOKEN', 'Header name', name);
+ } else if (isPseudoHeader(name)) {
+ err = new errors.Error('ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED');
+ } else if (value === undefined || value === null) {
+ err = new errors.TypeError('ERR_HTTP_INVALID_HEADER_VALUE', value, name);
+ }
+ if (err) {
+ Error.captureStackTrace(err, assertValidHeader);
+ throw err;
+ }
}
function isPseudoHeader(name) {
diff --git a/test/parallel/test-http-mutable-headers.js b/test/parallel/test-http-mutable-headers.js
index 929a566caf5578..2473a08eb1978e 100644
--- a/test/parallel/test-http-mutable-headers.js
+++ b/test/parallel/test-http-mutable-headers.js
@@ -61,9 +61,9 @@ const s = http.createServer(common.mustCall((req, res) => {
common.expectsError(
() => res.setHeader('someHeader'),
{
- code: 'ERR_MISSING_ARGS',
+ code: 'ERR_HTTP_INVALID_HEADER_VALUE',
type: TypeError,
- message: 'The "value" argument must be specified'
+ message: 'Invalid value "undefined" for header "someHeader"'
}
);
common.expectsError(
diff --git a/test/parallel/test-http-outgoing-proto.js b/test/parallel/test-http-outgoing-proto.js
index 22eba0981f6fc2..7db252dfbf9855 100644
--- a/test/parallel/test-http-outgoing-proto.js
+++ b/test/parallel/test-http-outgoing-proto.js
@@ -34,9 +34,9 @@ assert.throws(() => {
const outgoingMessage = new OutgoingMessage();
outgoingMessage.setHeader('test');
}, common.expectsError({
- code: 'ERR_MISSING_ARGS',
+ code: 'ERR_HTTP_INVALID_HEADER_VALUE',
type: TypeError,
- message: 'The "value" argument must be specified'
+ message: 'Invalid value "undefined" for header "test"'
}));
assert.throws(() => {
diff --git a/test/parallel/test-http-write-head.js b/test/parallel/test-http-write-head.js
index 70ad5935a92690..e254f8d64da349 100644
--- a/test/parallel/test-http-write-head.js
+++ b/test/parallel/test-http-write-head.js
@@ -44,9 +44,9 @@ const s = http.createServer(common.mustCall((req, res) => {
common.expectsError(
() => res.setHeader('foo', undefined),
{
- code: 'ERR_MISSING_ARGS',
+ code: 'ERR_HTTP_INVALID_HEADER_VALUE',
type: TypeError,
- message: 'The "value" argument must be specified'
+ message: 'Invalid value "undefined" for header "foo"'
}
);
diff --git a/test/parallel/test-http2-compat-serverresponse-headers.js b/test/parallel/test-http2-compat-serverresponse-headers.js
index aae1d96c552ebe..a46c7348ae9477 100644
--- a/test/parallel/test-http2-compat-serverresponse-headers.js
+++ b/test/parallel/test-http2-compat-serverresponse-headers.js
@@ -83,16 +83,16 @@ server.listen(0, common.mustCall(function() {
assert.throws(function() {
response.setHeader(real, null);
}, common.expectsError({
- code: 'ERR_HTTP2_INVALID_HEADER_VALUE',
+ code: 'ERR_HTTP_INVALID_HEADER_VALUE',
type: TypeError,
- message: 'Value must not be undefined or null'
+ message: 'Invalid value "null" for header "foo-bar"'
}));
assert.throws(function() {
response.setHeader(real, undefined);
}, common.expectsError({
- code: 'ERR_HTTP2_INVALID_HEADER_VALUE',
+ code: 'ERR_HTTP_INVALID_HEADER_VALUE',
type: TypeError,
- message: 'Value must not be undefined or null'
+ message: 'Invalid value "undefined" for header "foo-bar"'
}));
common.expectsError(
() => response.setHeader(), // header name undefined
diff --git a/test/parallel/test-http2-compat-serverresponse-trailers.js b/test/parallel/test-http2-compat-serverresponse-trailers.js
index 4d93e14dbec4b4..718a30c7cd45d9 100644
--- a/test/parallel/test-http2-compat-serverresponse-trailers.js
+++ b/test/parallel/test-http2-compat-serverresponse-trailers.js
@@ -26,17 +26,17 @@ server.listen(0, common.mustCall(() => {
common.expectsError(
() => response.setTrailer('test', undefined),
{
- code: 'ERR_HTTP2_INVALID_HEADER_VALUE',
+ code: 'ERR_HTTP_INVALID_HEADER_VALUE',
type: TypeError,
- message: 'Value must not be undefined or null'
+ message: 'Invalid value "undefined" for header "test"'
}
);
common.expectsError(
() => response.setTrailer('test', null),
{
- code: 'ERR_HTTP2_INVALID_HEADER_VALUE',
+ code: 'ERR_HTTP_INVALID_HEADER_VALUE',
type: TypeError,
- message: 'Value must not be undefined or null'
+ message: 'Invalid value "null" for header "test"'
}
);
common.expectsError(