From df0ecd2a930895d951294ea31a5f40e03dd5bf6d Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Fri, 12 Feb 2016 15:47:27 -0800 Subject: [PATCH] Ensure `_.isError` works with subclasses values. [closes #1994] --- lodash.js | 9 ++++++--- test/test.js | 57 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/lodash.js b/lodash.js index 9b35f92ff..b2a421028 100644 --- a/lodash.js +++ b/lodash.js @@ -9761,8 +9761,11 @@ * // => false */ function isError(value) { - return isObjectLike(value) && - typeof value.message == 'string' && objectToString.call(value) == errorTag; + if (!isObjectLike(value)) { + return false; + } + var Ctor = value.constructor; + return typeof Ctor == 'function' && objectToString.call(Ctor.prototype) == errorTag; } /** @@ -13121,7 +13124,7 @@ try { return apply(func, undefined, args); } catch (e) { - return isObject(e) ? e : new Error(e); + return isError(e) ? e : new Error(e); } }); diff --git a/test/test.js b/test/test.js index b340daa94..5680d4722 100644 --- a/test/test.js +++ b/test/test.js @@ -352,6 +352,32 @@ function(chr) { return /\s/.exec(chr); }) .join(''); + /** + * The custom error constructor. + * + * @private + * @param {string} message The error message. + * @returns {Object} Returns the new error object instance. + */ + function CustomError(message) { + this.name = 'CustomError'; + this.message = message; + } + + CustomError.prototype = lodashStable.create(Error.prototype); + + /** + * Removes all own enumerable properties from a given object. + * + * @private + * @param {Object} object The object to empty. + */ + function emptyObject(object) { + lodashStable.forOwn(object, function(value, key, object) { + delete object[key]; + }); + } + /** * Extracts the unwrapped value from its wrapper. * @@ -375,18 +401,6 @@ return result; } - /** - * Removes all own enumerable properties from a given object. - * - * @private - * @param {Object} object The object to empty. - */ - function emptyObject(object) { - lodashStable.forOwn(object, function(value, key, object) { - delete object[key]; - }); - } - /** * Sets a non-enumerable property value on `object`. * @@ -1519,13 +1533,6 @@ QUnit.test('should preserve custom errors', function(assert) { assert.expect(1); - function CustomError(message) { - this.name = 'CustomError'; - this.message = message; - } - - CustomError.prototype = lodashStable.create(Error.prototype); - var actual = _.attempt(function() { throw new CustomError('x'); }); assert.ok(actual instanceof CustomError); }); @@ -9219,6 +9226,12 @@ assert.deepEqual(actual, expected); }); + QUnit.test('should return `true` for subclassed values', function(assert) { + assert.expect(1); + + assert.strictEqual(_.isError(new CustomError('x')), true); + }); + QUnit.test('should return `false` for non error objects', function(assert) { assert.expect(12); @@ -11012,11 +11025,11 @@ (function() { QUnit.test('should return `false` for subclassed values', function(assert) { - assert.expect(8); + assert.expect(7); var funcs = [ - 'isArray', 'isBoolean', 'isDate', 'isError', - 'isFunction', 'isNumber', 'isRegExp', 'isString' + 'isArray', 'isBoolean', 'isDate', 'isFunction', + 'isNumber', 'isRegExp', 'isString' ]; lodashStable.each(funcs, function(methodName) {