@@ -166,6 +166,7 @@ import {
166166} from './metadata' ;
167167import {
168168 _extractTemplateStyleUrls ,
169+ createEmptyTemplate ,
169170 extractComponentStyleUrls ,
170171 extractInlineStyleResources ,
171172 extractTemplate ,
@@ -675,54 +676,70 @@ export class ComponentDecoratorHandler
675676
676677 template = preanalyzed ;
677678 } 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+ ) ;
704706
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+ }
715717
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+ }
726743 }
727744 }
728745 const templateResource = template . declaration . isInline
0 commit comments