Skip to content

Commit

Permalink
provide isError and use it in place of instanceof Error
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Grainger committed Mar 30, 2017
1 parent f403925 commit 0061c54
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"isNumber": false,
"isNumberNaN": false,
"isDate": false,
"isError": false,
"isArray": false,
"isFunction": false,
"isRegExp": false,
Expand Down
23 changes: 23 additions & 0 deletions src/Angular.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
isNumber,
isNumberNaN,
isDate,
isError,
isArray,
isFunction,
isRegExp,
Expand Down Expand Up @@ -673,6 +674,28 @@ function isDate(value) {
*/
var isArray = Array.isArray;

/**
* @ngdoc function
* @name angular.isError
* @module ng
* @kind function
*
* @description
* Determines if a reference is an `Error`.
*
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is an `Error`.
*/
function isError(value) {
var tag = toString(value);
switch (tag) {
case '[object Error]': return true;
case '[object Exception]': return true;
case '[object DOMException]': return true;
default: return value instanceof Error;
}
}

/**
* @ngdoc function
* @name angular.isFunction
Expand Down
2 changes: 1 addition & 1 deletion src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -3098,7 +3098,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
linkQueue = null;
}).catch(function(error) {
if (error instanceof Error) {
if (isError(error)) {
$exceptionHandler(error);
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/ng/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ function $LogProvider() {
};

function formatError(arg) {
if (arg instanceof Error) {
if (isError(arg)) {
if (arg.stack && formatStackTrace) {
arg = (arg.message && arg.stack.indexOf(arg.message) === -1)
? 'Error: ' + arg.message + '\n' + arg.stack
Expand Down
2 changes: 1 addition & 1 deletion src/ng/q.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) {
if (!toCheck.pur) {
toCheck.pur = true;
var errorMessage = 'Possibly unhandled rejection: ' + toDebugString(toCheck.value);
if (toCheck.value instanceof Error) {
if (isError(toCheck.value)) {
exceptionHandler(toCheck.value, errorMessage);
} else {
exceptionHandler(errorMessage);
Expand Down
2 changes: 1 addition & 1 deletion src/ngMock/angular-mocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ angular.mock.dump = function(object) {
} else if (angular.isObject(object)) {
if (angular.isFunction(object.$eval) && angular.isFunction(object.$apply)) {
out = serializeScope(object);
} else if (object instanceof Error) {
} else if (angular.isError(object)) {
out = object.stack || ('' + object.name + ': ' + object.message);
} else {
// TODO(i): this prevents methods being logged,
Expand Down
1 change: 1 addition & 0 deletions test/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"isNumber": false,
"isNumberNaN": false,
"isDate": false,
"isError": false,
"isArray": false,
"isFunction": false,
"isRegExp": false,
Expand Down
38 changes: 38 additions & 0 deletions test/AngularSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1861,6 +1861,44 @@ describe('angular', function() {
});
});

describe('isError', function() {
it('should not assume objects are errors', function() {
expect(isError({ message: 'A fake error', stack: 'no stack here'}))
.toBe(false);
});

it('should detect simple error instances', function() {
expect(isError(new Error()).toBe(true));
});

function testError(createError) {
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
try {
var error = createError(iframe.contentWindow);
expect(error instanceof Error).toBe(false);
expect(isError(error)).toBe(true);
} finally {
iframe.parentElement.removeChild(iframe);
}
}

it('should detect errors from another context', function() {
testError(function(win) {
return new win.Error();
});
});

it('should detect DOMException errors from another context', function() {
testError(function(win) {
try {
win.document.querySelectorAll('');
} catch (e) {
return e;
}
});
});
});

describe('isRegExp', function() {
it('should return true for RegExp object', function() {
Expand Down
2 changes: 1 addition & 1 deletion test/ng/qSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe('q', function() {
// The following private functions are used to help with logging for testing invocation of the
// promise callbacks.
function _argToString(arg) {
return (typeof arg === 'object' && !(arg instanceof Error)) ? toJson(arg) : '' + arg;
return (typeof arg === 'object' && !(isError(arg))) ? toJson(arg) : '' + arg;
}

function _argumentsToString(args) {
Expand Down

0 comments on commit 0061c54

Please sign in to comment.