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

Commit 52d3015

Browse files
committed
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
1 parent 6e7fbe7 commit 52d3015

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
@ngdoc error
2+
@name $injector:undef
3+
@fullName Undefined Value
4+
@description
5+
6+
This error results from registering a factory which does not return a value (or whose return value is undefined).
7+
8+
The following is an example of a factory which will throw this error upon injection:
9+
10+
```js
11+
angular.module("badModule", []).
12+
factory("badFactory", function() {
13+
doLotsOfThings();
14+
butDontReturnAValue();
15+
});
16+
```
17+
18+
In order to prevent the error, return a value of some sort, such as an object which exposes an API for working
19+
with the injected object.
20+
21+
```js
22+
angular.module("goodModule", []).
23+
factory("goodFactory", function() {
24+
doLotsOfThings();
25+
butDontReturnAValue();
26+
27+
return {
28+
doTheThing: function methodThatDoesAThing() {
29+
}
30+
};
31+
});
32+
```

src/auto/injector.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,17 @@ function createInjector(modulesToLoad, strictDi) {
663663
return providerCache[name + providerSuffix] = provider_;
664664
}
665665

666-
function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); }
666+
function enforceReturnValue(name, factory) {
667+
return function enforcedReturnValue() {
668+
var result = instanceInjector.invoke(factory);
669+
if (isUndefined(result)) {
670+
throw $injectorMinErr('undef', "Provider '{0}' must return a value from $get factory method.", name);
671+
}
672+
return result;
673+
};
674+
}
675+
676+
function factory(name, factoryFn) { return provider(name, { $get: enforceReturnValue(name, factoryFn) }); }
667677

668678
function service(name, constructor) {
669679
return factory(name, ['$injector', function($injector) {

test/auto/injectorSpec.js

+10
Original file line numberDiff line numberDiff line change
@@ -983,4 +983,14 @@ describe('strict-di injector', function() {
983983
}).toThrowMinErr('$injector', 'strictdi');
984984
});
985985
});
986+
987+
988+
it('should throw if factory does not return a value', function() {
989+
module(function($provide) {
990+
$provide.factory('$test', function() {});
991+
});
992+
expect(function() {
993+
inject(function($test) {});
994+
}).toThrowMinErr('$injector', 'undef');
995+
});
986996
});

0 commit comments

Comments
 (0)