@@ -75,7 +75,7 @@ export class TSDocConfigFile {
75
75
76
76
this . _extendsFiles = [ ] ;
77
77
this . _filePath = '' ;
78
- this . _fileNotFound = true ;
78
+ this . _fileNotFound = false ;
79
79
this . _hasErrors = false ;
80
80
this . _fileMTime = 0 ;
81
81
this . _tsdocSchema = '' ;
@@ -102,8 +102,11 @@ export class TSDocConfigFile {
102
102
}
103
103
104
104
/**
105
- * If true, then the TSDocConfigFile object contains an empty state, because the `tsdoc.json` file could
106
- * not be found by the loader.
105
+ * If true, then the TSDocConfigFile object contains an empty state, because the `tsdoc.json` file
106
+ * was not found by the loader.
107
+ *
108
+ * @remarks
109
+ * A missing "tsdoc.json" file is not considered an error. It simply means that the defaults will be used.
107
110
*/
108
111
public get fileNotFound ( ) : boolean {
109
112
return this . _fileNotFound ;
@@ -278,8 +281,6 @@ export class TSDocConfigFile {
278
281
}
279
282
280
283
private _loadJsonObject ( configJson : IConfigJson ) : void {
281
- this . _fileNotFound = false ;
282
-
283
284
if ( configJson . $schema !== TSDocConfigFile . CURRENT_SCHEMA_URL ) {
284
285
this . _reportError ( {
285
286
messageId : TSDocMessageId . ConfigFileUnsupportedSchema ,
@@ -347,6 +348,10 @@ export class TSDocConfigFile {
347
348
referencingConfigFile : TSDocConfigFile | undefined ,
348
349
alreadyVisitedPaths : Set < string >
349
350
) : void {
351
+ // In case an exception is thrown, start by assuming that the file was not found; we'll revise
352
+ // this later upon success
353
+ this . _fileNotFound = true ;
354
+
350
355
if ( ! configFilePath ) {
351
356
this . _reportError ( {
352
357
messageId : TSDocMessageId . ConfigFileNotFound ,
@@ -367,6 +372,11 @@ export class TSDocConfigFile {
367
372
return ;
368
373
}
369
374
375
+ const configJsonContent : string = fs . readFileSync ( this . _filePath ) . toString ( ) ;
376
+ this . _fileMTime = fs . statSync ( this . _filePath ) . mtimeMs ;
377
+
378
+ this . _fileNotFound = false ;
379
+
370
380
const hashKey : string = fs . realpathSync ( this . _filePath ) ;
371
381
if ( referencingConfigFile && alreadyVisitedPaths . has ( hashKey ) ) {
372
382
this . _reportError ( {
@@ -378,20 +388,15 @@ export class TSDocConfigFile {
378
388
}
379
389
alreadyVisitedPaths . add ( hashKey ) ;
380
390
381
- const configJsonContent : string = fs . readFileSync ( this . _filePath ) . toString ( ) ;
382
- this . _fileMTime = fs . statSync ( this . _filePath ) . mtimeMs ;
383
-
384
391
let configJson : IConfigJson ;
385
392
try {
386
393
configJson = jju . parse ( configJsonContent , { mode : 'cjson' } ) ;
387
394
} catch ( e ) {
388
- this . log . addMessage (
389
- new ParserMessage ( {
390
- messageId : TSDocMessageId . ConfigInvalidJson ,
391
- messageText : 'Error parsing JSON input: ' + e . message ,
392
- textRange : TextRange . empty ,
393
- } )
394
- ) ;
395
+ this . _reportError ( {
396
+ messageId : TSDocMessageId . ConfigInvalidJson ,
397
+ messageText : 'Error parsing JSON input: ' + e . message ,
398
+ textRange : TextRange . empty ,
399
+ } ) ;
395
400
return ;
396
401
}
397
402
@@ -400,7 +405,18 @@ export class TSDocConfigFile {
400
405
const configFileFolder : string = path . dirname ( this . filePath ) ;
401
406
402
407
for ( const extendsField of this . extendsPaths ) {
403
- const resolvedExtendsPath : string = resolve . sync ( extendsField , { basedir : configFileFolder } ) ;
408
+ let resolvedExtendsPath : string ;
409
+ try {
410
+ resolvedExtendsPath = resolve . sync ( extendsField , { basedir : configFileFolder } ) ;
411
+ } catch ( e ) {
412
+ this . _reportError ( {
413
+ messageId : TSDocMessageId . ConfigFileUnresolvedExtends ,
414
+ messageText : `Unable to resolve "extends" reference to "${ extendsField } ": ` + e . message ,
415
+ textRange : TextRange . empty ,
416
+ } ) ;
417
+
418
+ return ;
419
+ }
404
420
405
421
const baseConfigFile : TSDocConfigFile = new TSDocConfigFile ( ) ;
406
422
@@ -616,20 +632,26 @@ export class TSDocConfigFile {
616
632
return 'No errors.' ;
617
633
}
618
634
619
- let result : string ;
635
+ let result : string = '' ;
620
636
621
- if ( this . filePath ) {
622
- result = `Errors encountered for ${ this . filePath } :\n` ;
623
- } else {
624
- result = `Errors encountered when loading TSDoc configuration:\n` ;
625
- }
637
+ if ( this . log . messages . length > 0 ) {
638
+ const errorNoun : string = this . log . messages . length > 1 ? 'Errors' : 'Error' ;
639
+ if ( this . filePath ) {
640
+ result += `${ errorNoun } encountered for ${ this . filePath } :\n` ;
641
+ } else {
642
+ result += `${ errorNoun } encountered when loading TSDoc configuration:\n` ;
643
+ }
626
644
627
- for ( const message of this . log . messages ) {
628
- result += ` ${ message . text } \n` ;
645
+ for ( const message of this . log . messages ) {
646
+ result += ` ${ message . text } \n` ;
647
+ }
629
648
}
630
649
631
650
for ( const extendsFile of this . extendsFiles ) {
632
651
if ( extendsFile . hasErrors ) {
652
+ if ( result !== '' ) {
653
+ result += '\n' ;
654
+ }
633
655
result += extendsFile . getErrorSummary ( ) ;
634
656
}
635
657
}
@@ -681,6 +703,8 @@ export class TSDocConfigFile {
681
703
// Note that setSupportForTag() automatically enables configuration.validation.reportUnsupportedTags
682
704
configuration . setSupportForTag ( tagDefinition , supported ) ;
683
705
} else {
706
+ // Note that this validation may depend partially on the preexisting state of the TSDocConfiguration
707
+ // object, so it cannot be performed during the TSConfigFile.loadFile() stage.
684
708
this . _reportError ( {
685
709
messageId : TSDocMessageId . ConfigFileUndefinedTag ,
686
710
messageText : `The "supportForTags" field refers to an undefined tag ${ JSON . stringify ( tagName ) } .` ,
0 commit comments