Skip to content

Commit 817091b

Browse files
committed
feat($compile): show module name during multidir error
Show module name if possible when multidir error happens. Closes angular#11775
1 parent 64d0518 commit 817091b

File tree

3 files changed

+55
-23
lines changed

3 files changed

+55
-23
lines changed

src/auto/injector.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,7 @@ function createInjector(modulesToLoad, strictDi) {
620620
providerSuffix = 'Provider',
621621
path = [],
622622
loadedModules = new HashMap([], true),
623+
namedModulesLoaded = [],
623624
providerCache = {
624625
$provide: {
625626
provider: supportObject(provider),
@@ -735,6 +736,7 @@ function createInjector(modulesToLoad, strictDi) {
735736

736737
try {
737738
if (isString(module)) {
739+
namedModulesLoaded.push(module);
738740
moduleFn = angularModule(module);
739741
runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);
740742
runInvokeQueue(moduleFn._invokeQueue);
@@ -843,7 +845,8 @@ function createInjector(modulesToLoad, strictDi) {
843845
annotate: createInjector.$$annotate,
844846
has: function(name) {
845847
return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);
846-
}
848+
},
849+
_namedModulesLoaded: namedModulesLoaded
847850
};
848851
}
849852
}

src/ng/compile.js

+27-2
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
852852
if (isObject(bindings.isolateScope)) {
853853
directive.$$isolateBindings = bindings.isolateScope;
854854
}
855+
directive._factory = directiveFactory;
855856
directives.push(directive);
856857
} catch (e) {
857858
$exceptionHandler(e);
@@ -2300,11 +2301,35 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
23002301
return a.index - b.index;
23012302
}
23022303

2304+
function getModuleNameByDirectiveName(directive) {
2305+
var moduleName = '';
2306+
2307+
forEach($injector._namedModulesLoaded, function(loadedModuleName) {
2308+
var loadedModule = angularModule(loadedModuleName);
2309+
forEach(loadedModule._invokeQueue, function(invokeItem) {
2310+
var invocationParams = invokeItem[2];
2311+
if (invokeItem[1] == 'directive' &&
2312+
invocationParams['0'] === directive.name &&
2313+
invocationParams['1'] === directive._factory) {
2314+
moduleName = loadedModule.name;
2315+
}
2316+
});
2317+
});
2318+
return moduleName;
2319+
}
23032320

23042321
function assertNoDuplicate(what, previousDirective, directive, element) {
2322+
2323+
function wrapModuleNameIfDefined(moduleName) {
2324+
return moduleName ?
2325+
(' (module: ' + moduleName + ')') :
2326+
'';
2327+
}
2328+
23052329
if (previousDirective) {
2306-
throw $compileMinErr('multidir', 'Multiple directives [{0}, {1}] asking for {2} on: {3}',
2307-
previousDirective.name, directive.name, what, startingTag(element));
2330+
throw $compileMinErr('multidir', 'Multiple directives [{0}{1}, {2}{3}] asking for {4} on: {5}',
2331+
previousDirective.name, wrapModuleNameIfDefined(getModuleNameByDirectiveName(previousDirective)),
2332+
directive.name, wrapModuleNameIfDefined(getModuleNameByDirectiveName(directive)), what, startingTag(element));
23082333
}
23092334
}
23102335

test/ng/compileSpec.js

+24-20
Original file line numberDiff line numberDiff line change
@@ -2127,9 +2127,11 @@ describe('$compile', function() {
21272127
describe('scope', function() {
21282128
var iscope;
21292129

2130-
beforeEach(module(function() {
2131-
forEach(['', 'a', 'b'], function(name) {
2132-
directive('scope' + uppercase(name), function(log) {
2130+
var fakeScopeMdl = angular.module('fakeScopeMdl', []);
2131+
2132+
forEach(['', 'a', 'b'], function(name) {
2133+
fakeScopeMdl
2134+
.directive('scope' + uppercase(name), function(log) {
21332135
return {
21342136
scope: true,
21352137
restrict: 'CA',
@@ -2140,8 +2142,8 @@ describe('$compile', function() {
21402142
}};
21412143
}
21422144
};
2143-
});
2144-
directive('iscope' + uppercase(name), function(log) {
2145+
})
2146+
.directive('iscope' + uppercase(name), function(log) {
21452147
return {
21462148
scope: {},
21472149
restrict: 'CA',
@@ -2153,8 +2155,8 @@ describe('$compile', function() {
21532155
};
21542156
}
21552157
};
2156-
});
2157-
directive('tscope' + uppercase(name), function(log) {
2158+
})
2159+
.directive('tscope' + uppercase(name), function(log) {
21582160
return {
21592161
scope: true,
21602162
restrict: 'CA',
@@ -2166,8 +2168,8 @@ describe('$compile', function() {
21662168
};
21672169
}
21682170
};
2169-
});
2170-
directive('stscope' + uppercase(name), function(log) {
2171+
})
2172+
.directive('stscope' + uppercase(name), function(log) {
21712173
return {
21722174
scope: true,
21732175
restrict: 'CA',
@@ -2179,8 +2181,8 @@ describe('$compile', function() {
21792181
};
21802182
}
21812183
};
2182-
});
2183-
directive('trscope' + uppercase(name), function(log) {
2184+
})
2185+
.directive('trscope' + uppercase(name), function(log) {
21842186
return {
21852187
scope: true,
21862188
replace: true,
@@ -2193,8 +2195,8 @@ describe('$compile', function() {
21932195
};
21942196
}
21952197
};
2196-
});
2197-
directive('tiscope' + uppercase(name), function(log) {
2198+
})
2199+
.directive('tiscope' + uppercase(name), function(log) {
21982200
return {
21992201
scope: {},
22002202
restrict: 'CA',
@@ -2207,8 +2209,8 @@ describe('$compile', function() {
22072209
};
22082210
}
22092211
};
2210-
});
2211-
directive('stiscope' + uppercase(name), function(log) {
2212+
})
2213+
.directive('stiscope' + uppercase(name), function(log) {
22122214
return {
22132215
scope: {},
22142216
restrict: 'CA',
@@ -2222,17 +2224,19 @@ describe('$compile', function() {
22222224
}
22232225
};
22242226
});
2225-
});
2226-
directive('log', function(log) {
2227+
});
2228+
2229+
fakeScopeMdl
2230+
.directive('log', function(log) {
22272231
return {
22282232
restrict: 'CA',
22292233
link: {pre: function(scope) {
22302234
log('log-' + scope.$id + '-' + (scope.$parent && scope.$parent.$id || 'no-parent'));
22312235
}}
22322236
};
22332237
});
2234-
}));
22352238

2239+
beforeEach(module('fakeScopeMdl'));
22362240

22372241
it('should allow creation of new scopes', inject(function($rootScope, $compile, log) {
22382242
element = $compile('<div><span scope><a log></a></span></div>')($rootScope);
@@ -2335,7 +2339,7 @@ describe('$compile', function() {
23352339
function($rootScope, $compile) {
23362340
expect(function() {
23372341
$compile('<div class="iscope-a; scope-b"></div>');
2338-
}).toThrowMinErr('$compile', 'multidir', 'Multiple directives [iscopeA, scopeB] asking for new/isolated scope on: ' +
2342+
}).toThrowMinErr('$compile', 'multidir', 'Multiple directives [iscopeA (module: fakeScopeMdl), scopeB (module: fakeScopeMdl)] asking for new/isolated scope on: ' +
23392343
'<div class="iscope-a; scope-b">');
23402344
})
23412345
);
@@ -2354,7 +2358,7 @@ describe('$compile', function() {
23542358
inject(function($compile) {
23552359
expect(function() {
23562360
$compile('<div class="iscope-a; high-priority-scope"></div>');
2357-
}).toThrowMinErr('$compile', 'multidir', 'Multiple directives [highPriorityScope, iscopeA] asking for new/isolated scope on: ' +
2361+
}).toThrowMinErr('$compile', 'multidir', 'Multiple directives [highPriorityScope, iscopeA (module: fakeScopeMdl)] asking for new/isolated scope on: ' +
23582362
'<div class="iscope-a; high-priority-scope">');
23592363
});
23602364
});

0 commit comments

Comments
 (0)