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

Commit 013b522

Browse files
ocombecaitp
authored andcommitted
feat($injector): print caller name in "unknown provider" errors (when available)
NGEUROPE!!!!! Closes #8135 Closes #9721
1 parent 7c6be43 commit 013b522

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

src/auto/injector.js

+12-8
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ function annotate(fn, strictDi, name) {
179179
* Return an instance of the service.
180180
*
181181
* @param {string} name The name of the instance to retrieve.
182+
* @param {string} caller An optional string to provide the origin of the function call for error messages.
182183
* @return {*} The instance.
183184
*/
184185

@@ -629,14 +630,17 @@ function createInjector(modulesToLoad, strictDi) {
629630
}
630631
},
631632
providerInjector = (providerCache.$injector =
632-
createInternalInjector(providerCache, function() {
633+
createInternalInjector(providerCache, function(serviceName, caller) {
634+
if (angular.isString(caller)) {
635+
path.push(caller);
636+
}
633637
throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- '));
634638
})),
635639
instanceCache = {},
636640
instanceInjector = (instanceCache.$injector =
637-
createInternalInjector(instanceCache, function(servicename) {
638-
var provider = providerInjector.get(servicename + providerSuffix);
639-
return instanceInjector.invoke(provider.$get, provider, undefined, servicename);
641+
createInternalInjector(instanceCache, function(serviceName, caller) {
642+
var provider = providerInjector.get(serviceName + providerSuffix, caller);
643+
return instanceInjector.invoke(provider.$get, provider, undefined, serviceName);
640644
}));
641645

642646

@@ -671,7 +675,7 @@ function createInjector(modulesToLoad, strictDi) {
671675

672676
function enforceReturnValue(name, factory) {
673677
return function enforcedReturnValue() {
674-
var result = instanceInjector.invoke(factory, this, undefined, name);
678+
var result = instanceInjector.invoke(factory, this);
675679
if (isUndefined(result)) {
676680
throw $injectorMinErr('undef', "Provider '{0}' must return a value from $get factory method.", name);
677681
}
@@ -766,7 +770,7 @@ function createInjector(modulesToLoad, strictDi) {
766770

767771
function createInternalInjector(cache, factory) {
768772

769-
function getService(serviceName) {
773+
function getService(serviceName, caller) {
770774
if (cache.hasOwnProperty(serviceName)) {
771775
if (cache[serviceName] === INSTANTIATING) {
772776
throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
@@ -777,7 +781,7 @@ function createInjector(modulesToLoad, strictDi) {
777781
try {
778782
path.unshift(serviceName);
779783
cache[serviceName] = INSTANTIATING;
780-
return cache[serviceName] = factory(serviceName);
784+
return cache[serviceName] = factory(serviceName, caller);
781785
} catch (err) {
782786
if (cache[serviceName] === INSTANTIATING) {
783787
delete cache[serviceName];
@@ -809,7 +813,7 @@ function createInjector(modulesToLoad, strictDi) {
809813
args.push(
810814
locals && locals.hasOwnProperty(key)
811815
? locals[key]
812-
: getService(key)
816+
: getService(key, serviceName)
813817
);
814818
}
815819
if (isArray(fn)) {

test/auto/injectorSpec.js

+19-1
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ describe('injector', function() {
44
var providers;
55
var injector;
66
var providerInjector;
7+
var controllerProvider;
78

8-
beforeEach(module(function($provide, $injector) {
9+
beforeEach(module(function($provide, $injector, $controllerProvider) {
910
providers = function(name, factory, annotations) {
1011
$provide.factory(name, extend(factory, annotations || {}));
1112
};
1213
providerInjector = $injector;
14+
controllerProvider = $controllerProvider;
1315
}));
1416
beforeEach(inject(function($injector) {
1517
injector = $injector;
@@ -74,6 +76,22 @@ describe('injector', function() {
7476
});
7577

7678

79+
it('should provide the caller name if given', function(done) {
80+
expect(function() {
81+
injector.get('idontexist', 'callerName');
82+
}).toThrowMinErr("$injector", "unpr", "Unknown provider: idontexistProvider <- idontexist <- callerName");
83+
});
84+
85+
86+
it('should provide the caller name for controllers', function(done) {
87+
controllerProvider.register('myCtrl', function(idontexist) {});
88+
var $controller = injector.get('$controller');
89+
expect(function() {
90+
$controller('myCtrl', {$scope: {}});
91+
}).toThrowMinErr("$injector", "unpr", "Unknown provider: idontexistProvider <- idontexist <- myCtrl");
92+
});
93+
94+
7795
it('should not corrupt the cache when an object fails to get instantiated', function() {
7896
expect(function() {
7997
injector.get('idontexist');

0 commit comments

Comments
 (0)