util: improve internal isError()
validation
The current internal isError function checked the toString value instead of using the more precise `util.types.isNativeError()` check. The `instanceof` check is not removed due to possible errors that are not native but still an instance of Error. PR-URL: https://github.com/nodejs/node/pull/24746 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
This commit is contained in:
parent
1fe824bcbb
commit
2b5f2bc68b
@ -12,6 +12,9 @@ const {
|
|||||||
arrow_message_private_symbol: kArrowMessagePrivateSymbolIndex,
|
arrow_message_private_symbol: kArrowMessagePrivateSymbolIndex,
|
||||||
decorated_private_symbol: kDecoratedPrivateSymbolIndex
|
decorated_private_symbol: kDecoratedPrivateSymbolIndex
|
||||||
} = internalBinding('util');
|
} = internalBinding('util');
|
||||||
|
const {
|
||||||
|
isNativeError
|
||||||
|
} = internalBinding('types');
|
||||||
|
|
||||||
const { errmap } = internalBinding('uv');
|
const { errmap } = internalBinding('uv');
|
||||||
|
|
||||||
@ -26,7 +29,10 @@ function removeColors(str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isError(e) {
|
function isError(e) {
|
||||||
return objectToString(e) === '[object Error]' || e instanceof Error;
|
// An error could be an instance of Error while not being a native error
|
||||||
|
// or could be from a different realm and not be instance of Error but still
|
||||||
|
// be a native error.
|
||||||
|
return isNativeError(e) || e instanceof Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
function objectToString(o) {
|
function objectToString(o) {
|
||||||
|
12
lib/util.js
12
lib/util.js
@ -42,10 +42,16 @@ const {
|
|||||||
const {
|
const {
|
||||||
deprecate,
|
deprecate,
|
||||||
getSystemErrorName: internalErrorName,
|
getSystemErrorName: internalErrorName,
|
||||||
isError,
|
|
||||||
promisify,
|
promisify,
|
||||||
} = require('internal/util');
|
} = require('internal/util');
|
||||||
|
|
||||||
|
const ReflectApply = Reflect.apply;
|
||||||
|
|
||||||
|
function uncurryThis(func) {
|
||||||
|
return (thisArg, ...args) => ReflectApply(func, thisArg, args);
|
||||||
|
}
|
||||||
|
const objectToString = uncurryThis(Object.prototype.toString);
|
||||||
|
|
||||||
let CIRCULAR_ERROR_MESSAGE;
|
let CIRCULAR_ERROR_MESSAGE;
|
||||||
let internalDeepEqual;
|
let internalDeepEqual;
|
||||||
|
|
||||||
@ -443,7 +449,9 @@ module.exports = exports = {
|
|||||||
isRegExp,
|
isRegExp,
|
||||||
isObject,
|
isObject,
|
||||||
isDate,
|
isDate,
|
||||||
isError,
|
isError(e) {
|
||||||
|
return objectToString(e) === '[object Error]' || e instanceof Error;
|
||||||
|
},
|
||||||
isFunction,
|
isFunction,
|
||||||
isPrimitive,
|
isPrimitive,
|
||||||
log,
|
log,
|
||||||
|
37
test/parallel/test-internal-util-helpers.js
Normal file
37
test/parallel/test-internal-util-helpers.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Flags: --expose-internals
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
require('../common');
|
||||||
|
const assert = require('assert');
|
||||||
|
const { types } = require('util');
|
||||||
|
const { isError } = require('internal/util');
|
||||||
|
const vm = require('vm');
|
||||||
|
|
||||||
|
// Special cased errors. Test the internal function which is used in
|
||||||
|
// `util.inspect()`, the `repl` and maybe more. This verifies that errors from
|
||||||
|
// different realms, and non native instances of error are properly detected as
|
||||||
|
// error while definitely false ones are not detected. This is different than
|
||||||
|
// the public `util.isError()` function which falsy detects the fake errors as
|
||||||
|
// actual errors.
|
||||||
|
{
|
||||||
|
const fake = { [Symbol.toStringTag]: 'Error' };
|
||||||
|
assert(!types.isNativeError(fake));
|
||||||
|
assert(!(fake instanceof Error));
|
||||||
|
assert(!isError(fake));
|
||||||
|
|
||||||
|
const err = new Error('test');
|
||||||
|
const newErr = Object.create(
|
||||||
|
Object.getPrototypeOf(err),
|
||||||
|
Object.getOwnPropertyDescriptors(err));
|
||||||
|
Object.defineProperty(err, 'message', { value: err.message });
|
||||||
|
assert(types.isNativeError(err));
|
||||||
|
assert(!types.isNativeError(newErr));
|
||||||
|
assert(newErr instanceof Error);
|
||||||
|
assert(isError(newErr));
|
||||||
|
|
||||||
|
const context = vm.createContext({});
|
||||||
|
const differentRealmErr = vm.runInContext('new Error()', context);
|
||||||
|
assert(types.isNativeError(differentRealmErr));
|
||||||
|
assert(!(differentRealmErr instanceof Error));
|
||||||
|
assert(isError(differentRealmErr));
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user