From 3454e8072a113ff870263ec5576c29785c8b8483 Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Thu, 11 Aug 2016 20:28:28 +0200 Subject: [PATCH 1/4] feat($controller): throw error when requested controller is not registered Previously, it would throw the ng:areq error, which is less specific and just informs that the requested controller did not yield a function. Given how commonly controllers are used in Angular, it makes sense to have a specific error. The ng:areq error is still thrown when the registered controller is not a function. Closes #14980 --- docs/content/error/$controller/ctrlreg.ngdoc | 24 ++++++++++++++++++++ docs/content/error/ng/areq.ngdoc | 3 ++- src/ng/controller.js | 5 ++++ test/ng/controllerSpec.js | 7 +++++- test/ng/directive/ngControllerSpec.js | 9 ++++++++ 5 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 docs/content/error/$controller/ctrlreg.ngdoc diff --git a/docs/content/error/$controller/ctrlreg.ngdoc b/docs/content/error/$controller/ctrlreg.ngdoc new file mode 100644 index 000000000000..19208049a913 --- /dev/null +++ b/docs/content/error/$controller/ctrlreg.ngdoc @@ -0,0 +1,24 @@ +@ngdoc error +@name $controller:ctrlreg +@fullName A controller with this name is not registered. +@description + +This error occurs when the {@link ng.$controller `$controller()`} service is called +with a string that does not match any of the registered controllers. The controller service may have +been invoked directly, or indirectly through the {@link ng.ngController `ngController`} directive, +or when inside a {@link angular.Module#component component} / {@link angular.Module#directive directive} +definition (when using string notation for the controller property). + +Sources for this error can be: + +1. You have a typo in the {@link ng.ngController `ngController`} directive, +in a {@link angular.Module#component component} / {@link angular.Module#directive directive} +definition's controller property, or in the call to {@link ng.$controller `$controller()`}. +2. You have not registered the controller (neither via {@link angular.Module#controller `Module.controller`} +nor {@link ng.$controllerProvider#register `$controllerProvider.register()`}. +3. You have a typo in the *registered* controller name. +4. You want to use controllers defined on the `window`, but have turned off +{@link ng.$controllerProvider#allowGlobals `allowGlobals()`}. + + +Please consult the {@link ng.$controller $controller} service api docs to learn more. diff --git a/docs/content/error/ng/areq.ngdoc b/docs/content/error/ng/areq.ngdoc index 376ac035c00a..ddf1d408520b 100644 --- a/docs/content/error/ng/areq.ngdoc +++ b/docs/content/error/ng/areq.ngdoc @@ -5,4 +5,5 @@ AngularJS often asserts that certain values will be present and truthy using a helper function. If the assertion fails, this error is thrown. To fix this problem, -make sure that the value the assertion expects is defined and truthy. +make sure that the value the assertion expects is defined and matches the type mentioned in the +error. diff --git a/src/ng/controller.js b/src/ng/controller.js index b1cbdc5cf91d..f6c4a7c5abd1 100644 --- a/src/ng/controller.js +++ b/src/ng/controller.js @@ -122,6 +122,11 @@ function $ControllerProvider() { : getter(locals.$scope, constructor, true) || (globals ? getter($window, constructor, true) : undefined); + if (!expression) { + throw $controllerMinErr('ctrlreg', + 'The controller with the name \'{0}\' is not registered.', constructor); + } + assertArgFn(expression, constructor, true); } diff --git a/test/ng/controllerSpec.js b/test/ng/controllerSpec.js index f872e42c3cb6..a41cd77543e5 100644 --- a/test/ng/controllerSpec.js +++ b/test/ng/controllerSpec.js @@ -161,6 +161,12 @@ describe('$controller', function() { }).toThrow(); })); + it('should throw ctrlreg when the controller name does not match a registered controller', inject(function($compile, $rootScope) { + expect(function() { + $controller('IDoNotExist', {$scope: {}}); + }).toThrowMinErr('$controller', 'ctrlreg', 'The controller with the name \'IDoNotExist\' is not registered.'); + })); + describe('ctrl as syntax', function() { @@ -227,7 +233,6 @@ describe('$controller', function() { 'Must match `__name__ as __id__` or `__name__`.'); }); - it('should allow identifiers containing `$`', function() { var scope = {}; diff --git a/test/ng/directive/ngControllerSpec.js b/test/ng/directive/ngControllerSpec.js index 89bd23f9c781..b6d734159bd6 100644 --- a/test/ng/directive/ngControllerSpec.js +++ b/test/ng/directive/ngControllerSpec.js @@ -150,4 +150,13 @@ describe('ngController', function() { $httpBackend.flush(); expect(controllerScope.name).toBeUndefined(); })); + + it('should throw ctrlreg when the controller name does not match a registered controller', inject(function($compile, $rootScope) { + element = jqLite('
'); + + expect(function() { + element = $compile(element)($rootScope); + }).toThrowMinErr('$controller', 'ctrlreg', 'The controller with the name \'IDoNotExist\' is not registered.'); + })); + }); From 1268b9dd518f62c93ea2a741257a936650bbfb00 Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Thu, 11 Aug 2016 22:25:04 +0200 Subject: [PATCH 2/4] test longer timeout --- karma-shared.conf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/karma-shared.conf.js b/karma-shared.conf.js index ee4c78d00d7b..b1bc4bc1d76e 100644 --- a/karma-shared.conf.js +++ b/karma-shared.conf.js @@ -135,7 +135,7 @@ module.exports = function(config, specificOptions) { config.logLevel = config.LOG_DEBUG; // Karma (with socket.io 1.x) buffers by 50 and 50 tests can take a long time on IEs;-) - config.browserNoActivityTimeout = 120000; + config.browserNoActivityTimeout = 140000; config.browserStack.build = buildLabel; config.browserStack.startTunnel = false; From 2e26d7b13e50c534d93ad39785615db2e4c66c00 Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Fri, 12 Aug 2016 16:38:58 +0200 Subject: [PATCH 3/4] improve docs, remove one test --- docs/content/error/$controller/ctrlreg.ngdoc | 15 +++++++-------- test/ng/controllerSpec.js | 4 ++-- test/ng/directive/ngControllerSpec.js | 8 -------- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/docs/content/error/$controller/ctrlreg.ngdoc b/docs/content/error/$controller/ctrlreg.ngdoc index 19208049a913..64a77d7abbca 100644 --- a/docs/content/error/$controller/ctrlreg.ngdoc +++ b/docs/content/error/$controller/ctrlreg.ngdoc @@ -5,20 +5,19 @@ This error occurs when the {@link ng.$controller `$controller()`} service is called with a string that does not match any of the registered controllers. The controller service may have -been invoked directly, or indirectly through the {@link ng.ngController `ngController`} directive, -or when inside a {@link angular.Module#component component} / {@link angular.Module#directive directive} -definition (when using string notation for the controller property). +been invoked directly, or indirectly, for example through the {@link ng.ngController `ngController`} directive, +or inside a {@link angular.Module#component component} / {@link angular.Module#directive directive} / +{@link ngRoute.$routeProvider#when route} definition (when using a string for the controller property). +Third-party modules can also instantiate controllers with the {@link ng.$controller `$controller()`} service. -Sources for this error can be: +Causes for this error can be: -1. You have a typo in the {@link ng.ngController `ngController`} directive, -in a {@link angular.Module#component component} / {@link angular.Module#directive directive} +1. Your reference to the controller has a typo. For example, in +the {@link ng.ngController `ngController`} directive attribute, in a {@link angular.Module#component component} definition's controller property, or in the call to {@link ng.$controller `$controller()`}. 2. You have not registered the controller (neither via {@link angular.Module#controller `Module.controller`} nor {@link ng.$controllerProvider#register `$controllerProvider.register()`}. 3. You have a typo in the *registered* controller name. -4. You want to use controllers defined on the `window`, but have turned off -{@link ng.$controllerProvider#allowGlobals `allowGlobals()`}. Please consult the {@link ng.$controller $controller} service api docs to learn more. diff --git a/test/ng/controllerSpec.js b/test/ng/controllerSpec.js index a41cd77543e5..8fca250c9fba 100644 --- a/test/ng/controllerSpec.js +++ b/test/ng/controllerSpec.js @@ -161,11 +161,11 @@ describe('$controller', function() { }).toThrow(); })); - it('should throw ctrlreg when the controller name does not match a registered controller', inject(function($compile, $rootScope) { + it('should throw ctrlreg when the controller name does not match a registered controller', function() { expect(function() { $controller('IDoNotExist', {$scope: {}}); }).toThrowMinErr('$controller', 'ctrlreg', 'The controller with the name \'IDoNotExist\' is not registered.'); - })); + }); describe('ctrl as syntax', function() { diff --git a/test/ng/directive/ngControllerSpec.js b/test/ng/directive/ngControllerSpec.js index b6d734159bd6..f78baa7fff7e 100644 --- a/test/ng/directive/ngControllerSpec.js +++ b/test/ng/directive/ngControllerSpec.js @@ -151,12 +151,4 @@ describe('ngController', function() { expect(controllerScope.name).toBeUndefined(); })); - it('should throw ctrlreg when the controller name does not match a registered controller', inject(function($compile, $rootScope) { - element = jqLite('
'); - - expect(function() { - element = $compile(element)($rootScope); - }).toThrowMinErr('$controller', 'ctrlreg', 'The controller with the name \'IDoNotExist\' is not registered.'); - })); - }); From 70d60722e12587a2e53bb75df191d22275e0fc59 Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Fri, 12 Aug 2016 19:10:34 +0200 Subject: [PATCH 4/4] Update karma-shared.conf.js --- karma-shared.conf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/karma-shared.conf.js b/karma-shared.conf.js index b1bc4bc1d76e..ee4c78d00d7b 100644 --- a/karma-shared.conf.js +++ b/karma-shared.conf.js @@ -135,7 +135,7 @@ module.exports = function(config, specificOptions) { config.logLevel = config.LOG_DEBUG; // Karma (with socket.io 1.x) buffers by 50 and 50 tests can take a long time on IEs;-) - config.browserNoActivityTimeout = 140000; + config.browserNoActivityTimeout = 120000; config.browserStack.build = buildLabel; config.browserStack.startTunnel = false;