@@ -166,6 +166,7 @@ import {
166
166
} from './metadata' ;
167
167
import {
168
168
_extractTemplateStyleUrls ,
169
+ createEmptyTemplate ,
169
170
extractComponentStyleUrls ,
170
171
extractInlineStyleResources ,
171
172
extractTemplate ,
@@ -675,54 +676,70 @@ export class ComponentDecoratorHandler
675
676
676
677
template = preanalyzed ;
677
678
} else {
678
- const templateDecl = parseTemplateDeclaration (
679
- node ,
680
- decorator ,
681
- component ,
682
- containingFile ,
683
- this . evaluator ,
684
- this . depTracker ,
685
- this . resourceLoader ,
686
- this . defaultPreserveWhitespaces ,
687
- ) ;
688
- template = extractTemplate (
689
- node ,
690
- templateDecl ,
691
- this . evaluator ,
692
- this . depTracker ,
693
- this . resourceLoader ,
694
- {
695
- enableI18nLegacyMessageIdFormat : this . enableI18nLegacyMessageIdFormat ,
696
- i18nNormalizeLineEndingsInICUs : this . i18nNormalizeLineEndingsInICUs ,
697
- usePoisonedData : this . usePoisonedData ,
698
- enableBlockSyntax : this . enableBlockSyntax ,
699
- enableLetSyntax : this . enableLetSyntax ,
700
- preserveSignificantWhitespace : this . i18nPreserveSignificantWhitespace ,
701
- } ,
702
- this . compilationMode ,
703
- ) ;
679
+ try {
680
+ const templateDecl = parseTemplateDeclaration (
681
+ node ,
682
+ decorator ,
683
+ component ,
684
+ containingFile ,
685
+ this . evaluator ,
686
+ this . depTracker ,
687
+ this . resourceLoader ,
688
+ this . defaultPreserveWhitespaces ,
689
+ ) ;
690
+ template = extractTemplate (
691
+ node ,
692
+ templateDecl ,
693
+ this . evaluator ,
694
+ this . depTracker ,
695
+ this . resourceLoader ,
696
+ {
697
+ enableI18nLegacyMessageIdFormat : this . enableI18nLegacyMessageIdFormat ,
698
+ i18nNormalizeLineEndingsInICUs : this . i18nNormalizeLineEndingsInICUs ,
699
+ usePoisonedData : this . usePoisonedData ,
700
+ enableBlockSyntax : this . enableBlockSyntax ,
701
+ enableLetSyntax : this . enableLetSyntax ,
702
+ preserveSignificantWhitespace : this . i18nPreserveSignificantWhitespace ,
703
+ } ,
704
+ this . compilationMode ,
705
+ ) ;
704
706
705
- if (
706
- this . compilationMode === CompilationMode . LOCAL &&
707
- template . errors &&
708
- template . errors . length > 0
709
- ) {
710
- // Template errors are handled at the type check phase. But we skip this phase in local
711
- // compilation mode. As a result we need to handle the errors now and add them to the diagnostics.
712
- if ( diagnostics === undefined ) {
713
- diagnostics = [ ] ;
714
- }
707
+ if (
708
+ this . compilationMode === CompilationMode . LOCAL &&
709
+ template . errors &&
710
+ template . errors . length > 0
711
+ ) {
712
+ // Template errors are handled at the type check phase. But we skip this phase in local
713
+ // compilation mode. As a result we need to handle the errors now and add them to the diagnostics.
714
+ if ( diagnostics === undefined ) {
715
+ diagnostics = [ ] ;
716
+ }
715
717
716
- diagnostics . push (
717
- ...getTemplateDiagnostics (
718
- template . errors ,
719
- // Type check ID is required as part of the ype check, mainly for mapping the
720
- // diagnostic back to its source. But here we are generating the diagnostic outside
721
- // of the type check context, and so we skip the template ID.
722
- '' as TypeCheckId ,
723
- template . sourceMapping ,
724
- ) ,
725
- ) ;
718
+ diagnostics . push (
719
+ ...getTemplateDiagnostics (
720
+ template . errors ,
721
+ // Type check ID is required as part of the ype check, mainly for mapping the
722
+ // diagnostic back to its source. But here we are generating the diagnostic outside
723
+ // of the type check context, and so we skip the template ID.
724
+ '' as TypeCheckId ,
725
+ template . sourceMapping ,
726
+ ) ,
727
+ ) ;
728
+ }
729
+ } catch ( e ) {
730
+ if ( e instanceof FatalDiagnosticError ) {
731
+ diagnostics ??= [ ] ;
732
+ diagnostics . push ( e . toDiagnostic ( ) ) ;
733
+ isPoisoned = true ;
734
+ // Create an empty template for the missing/invalid template.
735
+ // A build will still fail in this case. However, for the language service,
736
+ // this allows the component to exist in the compiler registry and prevents
737
+ // cascading diagnostics within an IDE due to "missing" components. The
738
+ // originating template related errors will still be reported in the IDE.
739
+ template = createEmptyTemplate ( node , component , containingFile ) ;
740
+ } else {
741
+ throw e ;
742
+ }
726
743
}
727
744
}
728
745
const templateResource = template . declaration . isInline
0 commit comments