fix(core): log error instead of warning for unknown properties and elements (#36399)

Changes the Ivy unknown element/property messages from being logged with `console.warn` to `console.error`. This should make them a bit more visible without breaking existing apps. Furthermore, a lot of folks filter out warning messages in the dev tools' console, whereas errors are usually still shown.

BREAKING CHANGE:
Warnings about unknown elements are now logged as errors. This won't break your app, but it may trip up tools that expect nothing to be logged via `console.error`.

Fixes #35699.

PR Close #36399
This commit is contained in:
crisbeto
2020-04-02 20:58:03 +02:00
committed by Alex Rickabaugh
parent d9c4840a9c
commit 9d9d46f52b
7 changed files with 46 additions and 46 deletions

View File

@ -37,7 +37,7 @@ function elementStartFirstCreatePass(
const hasDirectives =
resolveDirectives(tView, lView, tNode, getConstant<string[]>(tViewConsts, localRefsIndex));
ngDevMode && warnAboutUnknownElement(tView, lView, native, tNode, hasDirectives);
ngDevMode && logUnknownElementError(tView, lView, native, tNode, hasDirectives);
if (tNode.mergedAttrs !== null) {
computeStaticStyling(tNode, tNode.mergedAttrs);
@ -173,7 +173,7 @@ export function ɵɵelement(
ɵɵelementEnd();
}
function warnAboutUnknownElement(
function logUnknownElementError(
tView: TView, lView: LView, element: RElement, tNode: TNode, hasDirectives: boolean): void {
const schemas = tView.schemas;
@ -199,17 +199,17 @@ function warnAboutUnknownElement(
!customElements.get(tagName));
if (isUnknown && !matchingSchemas(tView, lView, tagName)) {
let warning = `'${tagName}' is not a known element:\n`;
warning += `1. If '${
let message = `'${tagName}' is not a known element:\n`;
message += `1. If '${
tagName}' is an Angular component, then verify that it is part of this module.\n`;
if (tagName && tagName.indexOf('-') > -1) {
warning += `2. If '${
message += `2. If '${
tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.`;
} else {
warning +=
message +=
`2. To allow any element add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.`;
}
console.warn(warning);
console.error(message);
}
}
}

View File

@ -992,7 +992,7 @@ export function elementPropertyInternal<T>(
validateAgainstEventProperties(propName);
if (!validateProperty(tView, lView, element, propName, tNode)) {
// Return here since we only log warnings for unknown properties.
warnAboutUnknownProperty(propName, tNode);
logUnknownPropertyError(propName, tNode);
return;
}
ngDevMode.rendererSetProperty++;
@ -1011,7 +1011,7 @@ export function elementPropertyInternal<T>(
// If the node is a container and the property didn't
// match any of the inputs or schemas we should throw.
if (ngDevMode && !matchingSchemas(tView, lView, tNode.tagName)) {
warnAboutUnknownProperty(propName, tNode);
logUnknownPropertyError(propName, tNode);
}
}
}
@ -1105,12 +1105,12 @@ export function matchingSchemas(tView: TView, lView: LView, tagName: string|null
}
/**
* Logs a warning that a property is not supported on an element.
* Logs an error that a property is not supported on an element.
* @param propName Name of the invalid property.
* @param tNode Node on which we encountered the property.
*/
function warnAboutUnknownProperty(propName: string, tNode: TNode): void {
console.warn(
function logUnknownPropertyError(propName: string, tNode: TNode): void {
console.error(
`Can't bind to '${propName}' since it isn't a known property of '${tNode.tagName}'.`);
}