mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-28 11:56:03 +08:00
fix($injector): throw when factory $get method does not return a value
BREAKING CHANGE: Previously, not returning a value would fail silently, and an application trying to inject the value owuld inject an undefined value, quite possibly leading to a TypeError. Now, the application will fail entirely, and a reason will be given. Closes #4575 Closes #9210
This commit is contained in:
33
docs/content/error/$injector/undef.ngdoc
Normal file
33
docs/content/error/$injector/undef.ngdoc
Normal file
@@ -0,0 +1,33 @@
|
||||
@ngdoc error
|
||||
@name $injector:undef
|
||||
@fullName Undefined Value
|
||||
@description
|
||||
|
||||
This error results from registering a factory which does not return a value (or whose return value is undefined).
|
||||
|
||||
The following is an example of a factory which will throw this error upon injection:
|
||||
|
||||
```js
|
||||
angular.module("badModule", []).
|
||||
factory("badFactory", function() {
|
||||
doLotsOfThings();
|
||||
butDontReturnAValue();
|
||||
});
|
||||
```
|
||||
|
||||
In order to prevent the error, return a value of some sort, such as an object which exposes an API for working
|
||||
with the injected object.
|
||||
|
||||
```js
|
||||
angular.module("goodModule", []).
|
||||
factory("goodFactory", function() {
|
||||
doLotsOfThings();
|
||||
butDontReturnAValue();
|
||||
|
||||
return {
|
||||
doTheThing: function methodThatDoesAThing() {
|
||||
}
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
@@ -662,7 +662,21 @@ function createInjector(modulesToLoad, strictDi) {
|
||||
return providerCache[name + providerSuffix] = provider_;
|
||||
}
|
||||
|
||||
function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); }
|
||||
function enforceReturnValue(name, factory) {
|
||||
return function enforcedReturnValue() {
|
||||
var result = instanceInjector.invoke(factory);
|
||||
if (isUndefined(result)) {
|
||||
throw $injectorMinErr('undef', "Provider '{0}' must return a value from $get factory method.", name);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
function factory(name, factoryFn, enforce) {
|
||||
return provider(name, {
|
||||
$get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
|
||||
});
|
||||
}
|
||||
|
||||
function service(name, constructor) {
|
||||
return factory(name, ['$injector', function($injector) {
|
||||
@@ -670,7 +684,7 @@ function createInjector(modulesToLoad, strictDi) {
|
||||
}]);
|
||||
}
|
||||
|
||||
function value(name, val) { return factory(name, valueFn(val)); }
|
||||
function value(name, val) { return factory(name, valueFn(val), false); }
|
||||
|
||||
function constant(name, value) {
|
||||
assertNotHasOwnProperty(name, 'constant');
|
||||
|
||||
@@ -45,12 +45,12 @@ describe('injector', function() {
|
||||
// s6
|
||||
|
||||
|
||||
providers('s1', function() { log.push('s1'); }, {$inject: ['s2', 's5', 's6']});
|
||||
providers('s2', function() { log.push('s2'); }, {$inject: ['s3', 's4', 's5']});
|
||||
providers('s3', function() { log.push('s3'); }, {$inject: ['s6']});
|
||||
providers('s4', function() { log.push('s4'); }, {$inject: ['s3', 's5']});
|
||||
providers('s5', function() { log.push('s5'); });
|
||||
providers('s6', function() { log.push('s6'); });
|
||||
providers('s1', function() { log.push('s1'); return {}; }, {$inject: ['s2', 's5', 's6']});
|
||||
providers('s2', function() { log.push('s2'); return {}; }, {$inject: ['s3', 's4', 's5']});
|
||||
providers('s3', function() { log.push('s3'); return {}; }, {$inject: ['s6']});
|
||||
providers('s4', function() { log.push('s4'); return {}; }, {$inject: ['s3', 's5']});
|
||||
providers('s5', function() { log.push('s5'); return {}; });
|
||||
providers('s6', function() { log.push('s6'); return {}; });
|
||||
|
||||
injector.get('s1');
|
||||
|
||||
@@ -983,4 +983,14 @@ describe('strict-di injector', function() {
|
||||
}).toThrowMinErr('$injector', 'strictdi');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should throw if factory does not return a value', function() {
|
||||
module(function($provide) {
|
||||
$provide.factory('$test', function() {});
|
||||
});
|
||||
expect(function() {
|
||||
inject(function($test) {});
|
||||
}).toThrowMinErr('$injector', 'undef');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user