Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 92c3b75

Browse files
jurko-gospodneticgkalpak
authored andcommitted
fix(ngMock): fix collecting stack trace in inject() on IE10+, PhantomJS
Add support for collecting current stack trace information in browsers (e.g. IE10+, PhantomJS) that do not automatically store the current stack trace information in a newly created `Error` object's `stack` property, but only add it there once the `Error` gets thrown. The original implementation works fine in Firefox & Chrome, but fails on IE10+ and PhantomJS where it, for example, breaks Karma's error reporting in cases when an exception is thrown in a test like the following: ``` it('the holy crusade', inject(function() { var x = {}; x.holyGrail(); })); ``` In this case, the ngMock `inject()` implementation would incorrectly add the word `undefined` at the end of the collected error stack trace information, thus causing the main error description to be reported back to Karma as `undefined`. The added test makes sure this functionality: - works as expected in browsers supporting JavaScript stack trace collection, e.g. Chrome, Firefox, IE10+, Opera & PhantomJS - does not add any bogus stack track information in browsers that do not support JavaScript stack trace collection, e.g. IE9 Fixes #13591 Closes #13592 Closes #13593
1 parent a084030 commit 92c3b75

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

src/ngMock/angular-mocks.js

+6
Original file line numberDiff line numberDiff line change
@@ -2916,6 +2916,12 @@ angular.mock.$RootScopeDecorator = ['$delegate', function($delegate) {
29162916
window.inject = angular.mock.inject = function() {
29172917
var blockFns = Array.prototype.slice.call(arguments, 0);
29182918
var errorForStack = new Error('Declaration Location');
2919+
// IE10+ and PhanthomJS do not set stack trace information, until the error is thrown
2920+
if (!errorForStack.stack) {
2921+
try {
2922+
throw errorForStack;
2923+
} catch (e) {}
2924+
}
29192925
return wasInjectorCreated() ? workFn.call(currentSpec) : workFn;
29202926
/////////////////////
29212927
function workFn() {

test/ngMock/angular-mocksSpec.js

+45
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,51 @@ describe('ngMock', function() {
914914
});
915915
}).toThrow('test message');
916916
}));
917+
918+
describe('error stack trace when called outside of spec context', function() {
919+
// - Chrome, Firefox, Edge, Opera give us the stack trace as soon as an Error is created
920+
// - IE10+, PhantomJS give us the stack trace only once the error is thrown
921+
// - IE9 does not provide stack traces
922+
var stackTraceSupported = (function() {
923+
var error = new Error();
924+
if (!error.stack) {
925+
try {
926+
throw error;
927+
} catch (e) {}
928+
}
929+
930+
return !!error.stack;
931+
})();
932+
933+
function testCaller() {
934+
return inject(function() {
935+
throw new Error();
936+
});
937+
}
938+
var throwErrorFromInjectCallback = testCaller();
939+
940+
if (stackTraceSupported) {
941+
describe('on browsers supporting stack traces', function() {
942+
it('should update thrown Error stack trace with inject call location', function() {
943+
try {
944+
throwErrorFromInjectCallback();
945+
} catch (e) {
946+
expect(e.stack).toMatch('testCaller');
947+
}
948+
});
949+
});
950+
} else {
951+
describe('on browsers not supporting stack traces', function() {
952+
it('should not add stack trace information to thrown Error', function() {
953+
try {
954+
throwErrorFromInjectCallback();
955+
} catch (e) {
956+
expect(e.stack).toBeUndefined();
957+
}
958+
});
959+
});
960+
}
961+
});
917962
});
918963
});
919964

0 commit comments

Comments
 (0)