Skip to content

Commit 6bea059

Browse files
committed
fix($compile): reference correct directive name in ctreq error
Previously, ctreq would possibly reference the incorrect directive name, due to relying on a directiveName living outside of the closure which throws the exception, which can change before the call is ever made. This change saves the current value of directiveName as a property of the link function, which prevents this from occurring. Closes angular#7062 Closes angular#7067
1 parent fcdac65 commit 6bea059

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

src/ng/compile.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
13411341
if (pre) {
13421342
if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);
13431343
pre.require = directive.require;
1344+
pre.directiveName = directiveName;
13441345
if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
13451346
pre = cloneAndAnnotateFn(pre, {isolateScope: true});
13461347
}
@@ -1349,6 +1350,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
13491350
if (post) {
13501351
if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);
13511352
post.require = directive.require;
1353+
post.directiveName = directiveName;
13521354
if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
13531355
post = cloneAndAnnotateFn(post, {isolateScope: true});
13541356
}
@@ -1357,7 +1359,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
13571359
}
13581360

13591361

1360-
function getControllers(require, $element, elementControllers) {
1362+
function getControllers(directiveName, require, $element, elementControllers) {
13611363
var value, retrievalMethod = 'data', optional = false;
13621364
if (isString(require)) {
13631365
while((value = require.charAt(0)) == '^' || value == '?') {
@@ -1383,7 +1385,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
13831385
} else if (isArray(require)) {
13841386
value = [];
13851387
forEach(require, function(require) {
1386-
value.push(getControllers(require, $element, elementControllers));
1388+
value.push(getControllers(directiveName, require, $element, elementControllers));
13871389
});
13881390
}
13891391
return value;
@@ -1526,7 +1528,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15261528
try {
15271529
linkFn = preLinkFns[i];
15281530
linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs,
1529-
linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn);
1531+
linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), transcludeFn);
15301532
} catch (e) {
15311533
$exceptionHandler(e, startingTag($element));
15321534
}
@@ -1546,7 +1548,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15461548
try {
15471549
linkFn = postLinkFns[i];
15481550
linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs,
1549-
linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn);
1551+
linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), transcludeFn);
15501552
} catch (e) {
15511553
$exceptionHandler(e, startingTag($element));
15521554
}

test/ng/compileSpec.js

+21
Original file line numberDiff line numberDiff line change
@@ -3498,6 +3498,27 @@ describe('$compile', function() {
34983498
expect(element.text()).toBe('Hello');
34993499
});
35003500
});
3501+
3502+
3503+
it('should throw ctreq with correct directive name, regardless of order', function() {
3504+
module(function($compileProvider) {
3505+
$compileProvider.directive('aDir', valueFn({
3506+
restrict: "E",
3507+
require: "ngModel",
3508+
link: noop
3509+
}));
3510+
});
3511+
inject(function($compile, $rootScope) {
3512+
expect(function() {
3513+
// a-dir will cause a ctreq error to be thrown. Previously, the error would reference
3514+
// the last directive in the chain (which in this case would be ngClick), based on
3515+
// priority and alphabetical ordering. This test verifies that the ordering does not
3516+
// affect which directive is referenced in the minErr message.
3517+
element = $compile('<a-dir ng-click="foo=bar"></a-dir>')($rootScope);
3518+
}).toThrowMinErr('$compile', 'ctreq',
3519+
"Controller 'ngModel', required by directive 'aDir', can't be found!");
3520+
});
3521+
});
35013522
});
35023523

35033524

0 commit comments

Comments
 (0)