diff --git a/modules/angular2/src/core/di/exceptions.ts b/modules/angular2/src/core/di/exceptions.ts index 6e18ccf36b57..084b1a32ddef 100644 --- a/modules/angular2/src/core/di/exceptions.ts +++ b/modules/angular2/src/core/di/exceptions.ts @@ -222,8 +222,10 @@ export class NoAnnotationError extends BaseException { signature.push(parameter.map(stringify).join(' ')); } } - return "Cannot resolve all parameters for " + stringify(typeOrFunc) + "(" + - signature.join(', ') + "). " + 'Make sure they all have valid type or annotations.'; + return "Cannot resolve all parameters for '" + stringify(typeOrFunc) + "'(" + + signature.join(', ') + "). " + + "Make sure that all the parameters are decorated with Inject or have valid type annotations and that '" + + stringify(typeOrFunc) + "' is decorated with Injectable."; } } diff --git a/modules/angular2/src/facade/lang.dart b/modules/angular2/src/facade/lang.dart index bebddc051d6c..9323bff2371e 100644 --- a/modules/angular2/src/facade/lang.dart +++ b/modules/angular2/src/facade/lang.dart @@ -30,7 +30,15 @@ bool isPromise(obj) => obj is Future; bool isNumber(obj) => obj is num; bool isDate(obj) => obj is DateTime; -String stringify(obj) => obj.toString(); +String stringify(obj) { + final exp = new RegExp(r"from Function '(\w+)'"); + final str = obj.toString(); + if (exp.firstMatch(str) != null) { + return exp.firstMatch(str).group(1); + } else { + return str; + } +} int serializeEnum(val) { return val.index; diff --git a/modules/angular2/test/core/di/injector_spec.ts b/modules/angular2/test/core/di/injector_spec.ts index eed196dfe90b..41bc80970883 100644 --- a/modules/angular2/test/core/di/injector_spec.ts +++ b/modules/angular2/test/core/di/injector_spec.ts @@ -88,6 +88,8 @@ class NoAnnotations { constructor(secretDependency) {} } +function factoryFn(a) {} + export function main() { var dynamicProviders = [ provide('provider0', {useValue: 1}), @@ -142,10 +144,20 @@ export function main() { expect(car.engine).toBeAnInstanceOf(TurboEngine); }); - it('should throw when no type and not @Inject', () => { + it('should throw when no type and not @Inject (class case)', () => { expect(() => createInjector([NoAnnotations])) - .toThrowError('Cannot resolve all parameters for NoAnnotations(?). ' + - 'Make sure they all have valid type or annotations.'); + .toThrowError( + "Cannot resolve all parameters for 'NoAnnotations'(?). " + + 'Make sure that all the parameters are decorated with Inject or have valid type annotations ' + + "and that 'NoAnnotations' is decorated with Injectable."); + }); + + it('should throw when no type and not @Inject (factory case)', () => { + expect(() => createInjector([provide("someToken", {useFactory: factoryFn})])) + .toThrowError( + "Cannot resolve all parameters for 'factoryFn'(?). " + + 'Make sure that all the parameters are decorated with Inject or have valid type annotations ' + + "and that 'factoryFn' is decorated with Injectable."); }); it('should cache instances', () => {