Skip to content

Commit 3f1ff96

Browse files
committed
errors: make message non-enumerable
A error message should always be non-enumerable. This makes sure that is true for dns errors as well. It also adds another check in `common.expectsError` to make sure no other regressions are introduced going forward. Fixes #19716
1 parent 3567ea0 commit 3f1ff96

File tree

4 files changed

+27
-19
lines changed

4 files changed

+27
-19
lines changed

lib/internal/errors.js

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -537,34 +537,33 @@ function exceptionWithHostPort(err, syscall, address, port, additional) {
537537
}
538538

539539
/**
540-
* @param {number|string} err - A libuv error number or a c-ares error code
540+
* @param {number|string} code - A libuv error number or a c-ares error code
541541
* @param {string} syscall
542542
* @param {string} [hostname]
543543
* @returns {Error}
544544
*/
545-
function dnsException(err, syscall, hostname) {
546-
// eslint-disable-next-line no-restricted-syntax
547-
const ex = new Error();
545+
function dnsException(code, syscall, hostname) {
546+
let message;
548547
// FIXME(bnoordhuis) Remove this backwards compatibility nonsense and pass
549548
// the true error to the user. ENOTFOUND is not even a proper POSIX error!
550-
if (err === UV_EAI_MEMORY ||
551-
err === UV_EAI_NODATA ||
552-
err === UV_EAI_NONAME) {
553-
err = 'ENOTFOUND'; // Fabricated error name.
549+
if (code === UV_EAI_MEMORY ||
550+
code === UV_EAI_NODATA ||
551+
code === UV_EAI_NONAME) {
552+
code = 'ENOTFOUND'; // Fabricated error name.
554553
}
555-
if (typeof err === 'string') { // c-ares error code.
556-
const errHost = hostname ? ` ${hostname}` : '';
557-
ex.message = `${syscall} ${err}${errHost}`;
558-
// TODO(joyeecheung): errno is supposed to be a number, like in uvException
559-
ex.code = ex.errno = err;
560-
ex.syscall = syscall;
554+
if (typeof code === 'string') { // c-ares error code.
555+
message = `${syscall} ${code}${hostname ? ` ${hostname}` : ''}`;
561556
} else { // libuv error number
562-
const code = lazyInternalUtil().getSystemErrorName(err);
563-
ex.message = `${syscall} ${code}`;
564-
// TODO(joyeecheung): errno is supposed to be err, like in uvException
565-
ex.code = ex.errno = code;
566-
ex.syscall = syscall;
557+
code = lazyInternalUtil().getSystemErrorName(code);
558+
message = `${syscall} ${code}`;
567559
}
560+
// eslint-disable-next-line no-restricted-syntax
561+
const ex = new Error(message);
562+
// TODO(joyeecheung): errno is supposed to be a number / err, like in
563+
// uvException.
564+
ex.errno = code;
565+
ex.code = code;
566+
ex.syscall = syscall;
568567
if (hostname) {
569568
ex.hostname = hostname;
570569
}

test/common/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,9 @@ exports.expectsError = function expectsError(fn, settings, exact) {
691691
fn = undefined;
692692
}
693693
function innerFn(error) {
694+
const descriptor = Object.getOwnPropertyDescriptor(error, 'message');
695+
assert.strictEqual(descriptor.enumerable,
696+
false, 'The error message should be non-enumerable');
694697
if ('type' in settings) {
695698
const type = settings.type;
696699
if (type !== Error && !Error.isPrototypeOf(type)) {

test/parallel/test-dns-lookup.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ dns.lookup('example.com', common.mustCall((error, result, addressType) => {
9292
assert(error);
9393
assert.strictEqual(tickValue, 1);
9494
assert.strictEqual(error.code, 'ENOENT');
95+
const descriptor = Object.getOwnPropertyDescriptor(error, 'message');
96+
assert.strictEqual(descriptor.enumerable,
97+
false, 'The error message should be non-enumerable');
9598
}));
9699

97100
// Make sure that the error callback is called

test/parallel/test-dns-resolveany-bad-ancount.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ server.bind(0, common.mustCall(() => {
3030
assert.strictEqual(err.code, 'EBADRESP');
3131
assert.strictEqual(err.syscall, 'queryAny');
3232
assert.strictEqual(err.hostname, 'example.org');
33+
const descriptor = Object.getOwnPropertyDescriptor(err, 'message');
34+
assert.strictEqual(descriptor.enumerable,
35+
false, 'The error message should be non-enumerable');
3336
server.close();
3437
}));
3538
}));

0 commit comments

Comments
 (0)