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

PR-URL: https://github.com/nodejs/node/pull/19719
Fixes: https://github.com/nodejs/node/issues/19716
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Ruben Bridgewater 2018-04-01 07:38:47 +02:00
parent 354849eeb5
commit 22da2f731d
No known key found for this signature in database
GPG Key ID: F07496B3EB3C1762
4 changed files with 27 additions and 19 deletions

View File

@ -550,34 +550,33 @@ function exceptionWithHostPort(err, syscall, address, port, additional) {
} }
/** /**
* @param {number|string} err - A libuv error number or a c-ares error code * @param {number|string} code - A libuv error number or a c-ares error code
* @param {string} syscall * @param {string} syscall
* @param {string} [hostname] * @param {string} [hostname]
* @returns {Error} * @returns {Error}
*/ */
function dnsException(err, syscall, hostname) { function dnsException(code, syscall, hostname) {
// eslint-disable-next-line no-restricted-syntax let message;
const ex = new Error();
// FIXME(bnoordhuis) Remove this backwards compatibility nonsense and pass // FIXME(bnoordhuis) Remove this backwards compatibility nonsense and pass
// the true error to the user. ENOTFOUND is not even a proper POSIX error! // the true error to the user. ENOTFOUND is not even a proper POSIX error!
if (err === UV_EAI_MEMORY || if (code === UV_EAI_MEMORY ||
err === UV_EAI_NODATA || code === UV_EAI_NODATA ||
err === UV_EAI_NONAME) { code === UV_EAI_NONAME) {
err = 'ENOTFOUND'; // Fabricated error name. code = 'ENOTFOUND'; // Fabricated error name.
} }
if (typeof err === 'string') { // c-ares error code. if (typeof code === 'string') { // c-ares error code.
const errHost = hostname ? ` ${hostname}` : ''; message = `${syscall} ${code}${hostname ? ` ${hostname}` : ''}`;
ex.message = `${syscall} ${err}${errHost}`;
// TODO(joyeecheung): errno is supposed to be a number, like in uvException
ex.code = ex.errno = err;
ex.syscall = syscall;
} else { // libuv error number } else { // libuv error number
const code = lazyInternalUtil().getSystemErrorName(err); code = lazyInternalUtil().getSystemErrorName(code);
ex.message = `${syscall} ${code}`; message = `${syscall} ${code}`;
// TODO(joyeecheung): errno is supposed to be err, like in uvException
ex.code = ex.errno = code;
ex.syscall = syscall;
} }
// eslint-disable-next-line no-restricted-syntax
const ex = new Error(message);
// TODO(joyeecheung): errno is supposed to be a number / err, like in
// uvException.
ex.errno = code;
ex.code = code;
ex.syscall = syscall;
if (hostname) { if (hostname) {
ex.hostname = hostname; ex.hostname = hostname;
} }

View File

@ -691,6 +691,9 @@ exports.expectsError = function expectsError(fn, settings, exact) {
fn = undefined; fn = undefined;
} }
function innerFn(error) { function innerFn(error) {
const descriptor = Object.getOwnPropertyDescriptor(error, 'message');
assert.strictEqual(descriptor.enumerable,
false, 'The error message should be non-enumerable');
if ('type' in settings) { if ('type' in settings) {
const type = settings.type; const type = settings.type;
if (type !== Error && !Error.isPrototypeOf(type)) { if (type !== Error && !Error.isPrototypeOf(type)) {

View File

@ -92,6 +92,9 @@ dns.lookup('example.com', common.mustCall((error, result, addressType) => {
assert(error); assert(error);
assert.strictEqual(tickValue, 1); assert.strictEqual(tickValue, 1);
assert.strictEqual(error.code, 'ENOENT'); assert.strictEqual(error.code, 'ENOENT');
const descriptor = Object.getOwnPropertyDescriptor(error, 'message');
assert.strictEqual(descriptor.enumerable,
false, 'The error message should be non-enumerable');
})); }));
// Make sure that the error callback is called // Make sure that the error callback is called

View File

@ -30,6 +30,9 @@ server.bind(0, common.mustCall(() => {
assert.strictEqual(err.code, 'EBADRESP'); assert.strictEqual(err.code, 'EBADRESP');
assert.strictEqual(err.syscall, 'queryAny'); assert.strictEqual(err.syscall, 'queryAny');
assert.strictEqual(err.hostname, 'example.org'); assert.strictEqual(err.hostname, 'example.org');
const descriptor = Object.getOwnPropertyDescriptor(err, 'message');
assert.strictEqual(descriptor.enumerable,
false, 'The error message should be non-enumerable');
server.close(); server.close();
})); }));
})); }));