fix(ivy): incorrect injectable name logged in warning message on IE (#34305)
When we log DI errors we get the name of the provider via `SomeClass.name`. In IE functions that inherit from other functions don't have their own `name`, but they take the `name` from the lowest parent in the chain, before `Function`. I've added some changes to fall back to parsing out the function name from the function's string form. PR Close #34305
This commit is contained in:
parent
c2a904da09
commit
f79110c637
@ -223,17 +223,34 @@ export function getInheritedInjectableDef<T>(type: any): ɵɵInjectableDef<T>|nu
|
|||||||
(type[NG_PROV_DEF_FALLBACK] && type[NG_PROV_DEF_FALLBACK]()));
|
(type[NG_PROV_DEF_FALLBACK] && type[NG_PROV_DEF_FALLBACK]()));
|
||||||
|
|
||||||
if (def) {
|
if (def) {
|
||||||
|
const typeName = getTypeName(type);
|
||||||
// TODO(FW-1307): Re-add ngDevMode when closure can handle it
|
// TODO(FW-1307): Re-add ngDevMode when closure can handle it
|
||||||
// ngDevMode &&
|
// ngDevMode &&
|
||||||
console.warn(
|
console.warn(
|
||||||
`DEPRECATED: DI is instantiating a token "${type.name}" that inherits its @Injectable decorator but does not provide one itself.\n` +
|
`DEPRECATED: DI is instantiating a token "${typeName}" that inherits its @Injectable decorator but does not provide one itself.\n` +
|
||||||
`This will become an error in v10. Please add @Injectable() to the "${type.name}" class.`);
|
`This will become an error in v10. Please add @Injectable() to the "${typeName}" class.`);
|
||||||
return def;
|
return def;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets the name of a type, accounting for some cross-browser differences. */
|
||||||
|
function getTypeName(type: any): string {
|
||||||
|
// `Function.prototype.name` behaves differently between IE and other browsers. In most browsers
|
||||||
|
// it'll always return the name of the function itself, no matter how many other functions it
|
||||||
|
// inherits from. On IE the function doesn't have its own `name` property, but it takes it from
|
||||||
|
// the lowest level in the prototype chain. E.g. if we have `class Foo extends Parent` most
|
||||||
|
// browsers will evaluate `Foo.name` to `Foo` while IE will return `Parent`. We work around
|
||||||
|
// the issue by converting the function to a string and parsing its name out that way via a regex.
|
||||||
|
if (type.hasOwnProperty('name')) {
|
||||||
|
return type.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const match = ('' + type).match(/^function\s*([^\s(]+)/);
|
||||||
|
return match === null ? '' : match[1];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the injector def type in a way which is immune to accidentally reading inherited value.
|
* Read the injector def type in a way which is immune to accidentally reading inherited value.
|
||||||
*
|
*
|
||||||
|
@ -137,6 +137,9 @@
|
|||||||
{
|
{
|
||||||
"name": "getOwnDefinition"
|
"name": "getOwnDefinition"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getTypeName"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getUndecoratedInjectableFactory"
|
"name": "getUndecoratedInjectableFactory"
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user