Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 00f3c58

Browse files
crisbetoatscott
authored andcommitted
fix(core): log error instead of warning for unknown properties and elements (#35798)
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. Fixes #35699. PR Close #35798
1 parent ed44073 commit 00f3c58

File tree

7 files changed

+47
-47
lines changed

7 files changed

+47
-47
lines changed

‎packages/core/src/render3/instructions/element.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function elementStartFirstCreatePass(
3636

3737
const hasDirectives =
3838
resolveDirectives(tView, lView, tNode, getConstant<string[]>(tViewConsts, localRefsIndex));
39-
ngDevMode && warnAboutUnknownElement(tView, lView, native, tNode, hasDirectives);
39+
ngDevMode && logUnknownElementError(tView, lView, native, tNode, hasDirectives);
4040

4141
if (tNode.mergedAttrs !== null) {
4242
computeStaticStyling(tNode, tNode.mergedAttrs);
@@ -171,7 +171,7 @@ export function ɵɵelement(
171171
ɵɵelementEnd();
172172
}
173173

174-
function warnAboutUnknownElement(
174+
function logUnknownElementError(
175175
tView: TView, lView: LView, element: RElement, tNode: TNode, hasDirectives: boolean): void {
176176
const schemas = tView.schemas;
177177

@@ -197,17 +197,17 @@ function warnAboutUnknownElement(
197197
!customElements.get(tagName));
198198

199199
if (isUnknown && !matchingSchemas(tView, lView, tagName)) {
200-
let warning = `'${tagName}' is not a known element:\n`;
201-
warning +=
200+
let message = `'${tagName}' is not a known element:\n`;
201+
message +=
202202
`1. If '${tagName}' is an Angular component, then verify that it is part of this module.\n`;
203203
if (tagName && tagName.indexOf('-') > -1) {
204-
warning +=
204+
message +=
205205
`2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.`;
206206
} else {
207-
warning +=
207+
message +=
208208
`2. To allow any element add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.`;
209209
}
210-
console.warn(warning);
210+
console.error(message);
211211
}
212212
}
213213
}

‎packages/core/src/render3/instructions/shared.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,7 @@ export function elementPropertyInternal<T>(
962962
validateAgainstEventProperties(propName);
963963
if (!validateProperty(tView, lView, element, propName, tNode)) {
964964
// Return here since we only log warnings for unknown properties.
965-
warnAboutUnknownProperty(propName, tNode);
965+
logUnknownPropertyError(propName, tNode);
966966
return;
967967
}
968968
ngDevMode.rendererSetProperty++;
@@ -982,7 +982,7 @@ export function elementPropertyInternal<T>(
982982
// If the node is a container and the property didn't
983983
// match any of the inputs or schemas we should throw.
984984
if (ngDevMode && !matchingSchemas(tView, lView, tNode.tagName)) {
985-
warnAboutUnknownProperty(propName, tNode);
985+
logUnknownPropertyError(propName, tNode);
986986
}
987987
}
988988
}
@@ -1070,12 +1070,12 @@ export function matchingSchemas(tView: TView, lView: LView, tagName: string | nu
10701070
}
10711071

10721072
/**
1073-
* Logs a warning that a property is not supported on an element.
1073+
* Logs an error that a property is not supported on an element.
10741074
* @param propName Name of the invalid property.
10751075
* @param tNode Node on which we encountered the property.
10761076
*/
1077-
function warnAboutUnknownProperty(propName: string, tNode: TNode): void {
1078-
console.warn(
1077+
function logUnknownPropertyError(propName: string, tNode: TNode): void {
1078+
console.error(
10791079
`Can't bind to '${propName}' since it isn't a known property of '${tNode.tagName}'.`);
10801080
}
10811081

‎packages/core/test/acceptance/ng_module_spec.ts

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ describe('NgModule', () => {
9797
});
9898

9999
describe('schemas', () => {
100-
onlyInIvy('Unknown property warning logged instead of throwing an error')
100+
onlyInIvy('Unknown property logs an error message instead of throwing')
101101
.it('should throw on unknown props if NO_ERRORS_SCHEMA is absent', () => {
102102
@Component({
103103
selector: 'my-comp',
@@ -120,7 +120,7 @@ describe('NgModule', () => {
120120

121121
TestBed.configureTestingModule({imports: [MyModule]});
122122

123-
const spy = spyOn(console, 'warn');
123+
const spy = spyOn(console, 'error');
124124
const fixture = TestBed.createComponent(MyComp);
125125
fixture.detectChanges();
126126
expect(spy.calls.mostRecent().args[0])
@@ -185,15 +185,15 @@ describe('NgModule', () => {
185185
}).not.toThrow();
186186
});
187187

188-
onlyInIvy('unknown element check logs a warning rather than throwing')
189-
.it('should warn about unknown element without CUSTOM_ELEMENTS_SCHEMA for element with dash in tag name',
188+
onlyInIvy('unknown element check logs an error message rather than throwing')
189+
.it('should log an error about unknown element without CUSTOM_ELEMENTS_SCHEMA for element with dash in tag name',
190190
() => {
191191

192192
@Component({template: `<custom-el></custom-el>`})
193193
class MyComp {
194194
}
195195

196-
const spy = spyOn(console, 'warn');
196+
const spy = spyOn(console, 'error');
197197
TestBed.configureTestingModule({declarations: [MyComp]});
198198
const fixture = TestBed.createComponent(MyComp);
199199
fixture.detectChanges();
@@ -215,14 +215,14 @@ describe('NgModule', () => {
215215
}).toThrowError(/'custom-el' is not a known element/);
216216
});
217217

218-
onlyInIvy('unknown element check logs a warning rather than throwing')
219-
.it('should warn about unknown element without CUSTOM_ELEMENTS_SCHEMA for element without dash in tag name',
218+
onlyInIvy('unknown element check logs an error message rather than throwing')
219+
.it('should log an error about unknown element without CUSTOM_ELEMENTS_SCHEMA for element without dash in tag name',
220220
() => {
221221
@Component({template: `<custom></custom>`})
222222
class MyComp {
223223
}
224224

225-
const spy = spyOn(console, 'warn');
225+
const spy = spyOn(console, 'error');
226226
TestBed.configureTestingModule({declarations: [MyComp]});
227227
const fixture = TestBed.createComponent(MyComp);
228228
fixture.detectChanges();
@@ -245,8 +245,8 @@ describe('NgModule', () => {
245245
});
246246

247247
onlyInIvy('test relies on Ivy-specific AOT format')
248-
.it('should not log unknown element warning for AOT-compiled components', () => {
249-
const spy = spyOn(console, 'warn');
248+
.it('should not log unknown element error for AOT-compiled components', () => {
249+
const spy = spyOn(console, 'error');
250250

251251
/*
252252
* @Component({
@@ -310,13 +310,13 @@ describe('NgModule', () => {
310310
expect(spy).not.toHaveBeenCalled();
311311
});
312312

313-
onlyInIvy('unknown element check logs a warning rather than throwing')
314-
.it('should not warn about unknown elements with CUSTOM_ELEMENTS_SCHEMA', () => {
313+
onlyInIvy('unknown element check logs an error message rather than throwing')
314+
.it('should not log an error about unknown elements with CUSTOM_ELEMENTS_SCHEMA', () => {
315315
@Component({template: `<custom-el></custom-el>`})
316316
class MyComp {
317317
}
318318

319-
const spy = spyOn(console, 'warn');
319+
const spy = spyOn(console, 'error');
320320
TestBed.configureTestingModule({
321321
declarations: [MyComp],
322322
schemas: [CUSTOM_ELEMENTS_SCHEMA],
@@ -344,13 +344,13 @@ describe('NgModule', () => {
344344
}).not.toThrow();
345345
});
346346

347-
onlyInIvy('unknown element check logs a warning rather than throwing')
348-
.it('should not warn about unknown elements with NO_ERRORS_SCHEMA', () => {
347+
onlyInIvy('unknown element check logs an error message rather than throwing')
348+
.it('should not log an error about unknown elements with NO_ERRORS_SCHEMA', () => {
349349
@Component({template: `<custom-el></custom-el>`})
350350
class MyComp {
351351
}
352352

353-
const spy = spyOn(console, 'warn');
353+
const spy = spyOn(console, 'error');
354354
TestBed.configureTestingModule({
355355
declarations: [MyComp],
356356
schemas: [NO_ERRORS_SCHEMA],
@@ -378,8 +378,8 @@ describe('NgModule', () => {
378378
}).not.toThrow();
379379
});
380380

381-
onlyInIvy('unknown element check logs a warning rather than throwing')
382-
.it('should not warn about unknown elements if element matches a directive', () => {
381+
onlyInIvy('unknown element check logs an error message rather than throwing')
382+
.it('should not log an error about unknown elements if element matches a directive', () => {
383383
@Component({
384384
selector: 'custom-el',
385385
template: '',
@@ -391,7 +391,7 @@ describe('NgModule', () => {
391391
class MyComp {
392392
}
393393

394-
const spy = spyOn(console, 'warn');
394+
const spy = spyOn(console, 'error');
395395
TestBed.configureTestingModule({declarations: [MyComp, CustomEl]});
396396

397397
const fixture = TestBed.createComponent(MyComp);
@@ -420,8 +420,8 @@ describe('NgModule', () => {
420420
}).not.toThrow();
421421
});
422422

423-
onlyInIvy('unknown element check logs a warning rather than throwing')
424-
.it('should not warn for HTML elements inside an SVG foreignObject', () => {
423+
onlyInIvy('unknown element check logs an error message rather than throwing')
424+
.it('should not log an error for HTML elements inside an SVG foreignObject', () => {
425425
@Component({
426426
template: `
427427
<svg>
@@ -438,7 +438,7 @@ describe('NgModule', () => {
438438
class MyModule {
439439
}
440440

441-
const spy = spyOn(console, 'warn');
441+
const spy = spyOn(console, 'error');
442442
TestBed.configureTestingModule({imports: [MyModule]});
443443

444444
const fixture = TestBed.createComponent(MyComp);

‎packages/core/test/linker/integration_spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,7 +1632,7 @@ function declareTests(config?: {useJit: boolean}) {
16321632
});
16331633

16341634
describe('Property bindings', () => {
1635-
modifiedInIvy('Unknown property error throws an error instead of logging a warning')
1635+
modifiedInIvy('Unknown property error throws an error instead of logging it')
16361636
.it('should throw on bindings to unknown properties', () => {
16371637
TestBed.configureTestingModule({declarations: [MyComp]});
16381638
const template = '<div unknown="{{ctxProp}}"></div>';
@@ -1646,20 +1646,20 @@ function declareTests(config?: {useJit: boolean}) {
16461646
}
16471647
});
16481648

1649-
onlyInIvy('Unknown property warning logged instead of throwing an error')
1649+
onlyInIvy('Unknown property logs an error message instead of throwing')
16501650
.it('should throw on bindings to unknown properties', () => {
16511651
TestBed.configureTestingModule({declarations: [MyComp]});
16521652
const template = '<div unknown="{{ctxProp}}"></div>';
16531653
TestBed.overrideComponent(MyComp, {set: {template}});
16541654

1655-
const spy = spyOn(console, 'warn');
1655+
const spy = spyOn(console, 'error');
16561656
const fixture = TestBed.createComponent(MyComp);
16571657
fixture.detectChanges();
16581658
expect(spy.calls.mostRecent().args[0])
16591659
.toMatch(/Can't bind to 'unknown' since it isn't a known property of 'div'./);
16601660
});
16611661

1662-
modifiedInIvy('Unknown property error thrown instead of a warning')
1662+
modifiedInIvy('Unknown property error thrown instead of logging it')
16631663
.it('should throw on bindings to unknown properties', () => {
16641664
TestBed.configureTestingModule({imports: [CommonModule], declarations: [MyComp]});
16651665
const template = '<div *ngFor="let item in ctxArrProp">{{item}}</div>';
@@ -1675,12 +1675,12 @@ function declareTests(config?: {useJit: boolean}) {
16751675
}
16761676
});
16771677

1678-
onlyInIvy('Unknown property logs a warning instead of throwing an error')
1678+
onlyInIvy('Unknown property logs an error message instead of throwing it')
16791679
.it('should throw on bindings to unknown properties', () => {
16801680
TestBed.configureTestingModule({imports: [CommonModule], declarations: [MyComp]});
16811681
const template = '<div *ngFor="let item in ctxArrProp">{{item}}</div>';
16821682
TestBed.overrideComponent(MyComp, {set: {template}});
1683-
const spy = spyOn(console, 'warn');
1683+
const spy = spyOn(console, 'error');
16841684
const fixture = TestBed.createComponent(MyComp);
16851685
fixture.detectChanges();
16861686
expect(spy.calls.mostRecent().args[0])

‎packages/core/test/linker/ng_module_integration_spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ function declareTests(config?: {useJit: boolean}) {
250250
expect(() => createModule(SomeModule)).toThrowError(/Can't bind to 'someUnknownProp'/);
251251
});
252252

253-
onlyInIvy('Unknown property warning logged, instead of throwing an error')
253+
onlyInIvy('Unknown property error logged, instead of throwing')
254254
.it('should error on unknown bound properties on custom elements by default', () => {
255255
@Component({template: '<div [someUnknownProp]="true"></div>'})
256256
class ComponentUsingInvalidProperty {
@@ -260,7 +260,7 @@ function declareTests(config?: {useJit: boolean}) {
260260
class SomeModule {
261261
}
262262

263-
const spy = spyOn(console, 'warn');
263+
const spy = spyOn(console, 'error');
264264
const fixture = createComp(ComponentUsingInvalidProperty, SomeModule);
265265
fixture.detectChanges();
266266
expect(spy.calls.mostRecent().args[0]).toMatch(/Can't bind to 'someUnknownProp'/);

‎packages/core/test/linker/security_integration_spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,12 @@ function declareTests(config?: {useJit: boolean}) {
263263
.toThrowError(/Can't bind to 'xlink:href'/);
264264
});
265265

266-
onlyInIvy('Unknown property warning logged instead of throwing an error')
266+
onlyInIvy('Unknown property logs an error message instead of throwing')
267267
.it('should escape unsafe SVG attributes', () => {
268268
const template = `<svg:circle [xlink:href]="ctxProp">Text</svg:circle>`;
269269
TestBed.overrideComponent(SecuredComponent, {set: {template}});
270270

271-
const spy = spyOn(console, 'warn');
271+
const spy = spyOn(console, 'error');
272272
const fixture = TestBed.createComponent(SecuredComponent);
273273
fixture.detectChanges();
274274
expect(spy.calls.mostRecent().args[0]).toMatch(/Can't bind to 'xlink:href'/);

‎packages/platform-browser/test/testing_public_spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ Did you run and wait for 'resolveComponentResources()'?` :
937937
});
938938

939939

940-
modifiedInIvy(`Unknown property error thrown instead of logging a warning`)
940+
modifiedInIvy(`Unknown property error thrown instead of logging a message`)
941941
.it('should error on unknown bound properties on custom elements by default', () => {
942942
@Component({template: '<some-element [someUnknownProp]="true"></some-element>'})
943943
class ComponentUsingInvalidProperty {
@@ -956,13 +956,13 @@ Did you run and wait for 'resolveComponentResources()'?` :
956956
restoreJasmineIt();
957957
});
958958

959-
onlyInIvy(`Unknown property warning logged instead of an error`)
959+
onlyInIvy(`Unknown property error logged instead of throwing`)
960960
.it('should error on unknown bound properties on custom elements by default', () => {
961961
@Component({template: '<div [someUnknownProp]="true"></div>'})
962962
class ComponentUsingInvalidProperty {
963963
}
964964

965-
const spy = spyOn(console, 'warn');
965+
const spy = spyOn(console, 'error');
966966
withModule({declarations: [ComponentUsingInvalidProperty]}, () => {
967967
const fixture = TestBed.createComponent(ComponentUsingInvalidProperty);
968968
fixture.detectChanges();

0 commit comments

Comments
 (0)