Skip to content

Commit 0638417

Browse files
committed
Improve error report summaries (microsoft#45713)
1 parent 8894262 commit 0638417

File tree

47 files changed

+155
-99
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+155
-99
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4834,6 +4834,18 @@
48344834
"category": "Message",
48354835
"code": 6257
48364836
},
4837+
"Found 1 error in {1}": {
4838+
"category": "Message",
4839+
"code": 6258
4840+
},
4841+
"Found {0} errors in 1 file.": {
4842+
"category": "Message",
4843+
"code": 6259
4844+
},
4845+
"Found {0} errors in {1} files.": {
4846+
"category": "Message",
4847+
"code": 6260
4848+
},
48374849

48384850
"Enable project compilation": {
48394851
"category": "Message",

src/compiler/tsbuildPublic.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ namespace ts {
7676
return fileExtensionIs(fileName, Extension.Dts);
7777
}
7878

79-
export type ReportEmitErrorSummary = (errorCount: number) => void;
79+
export type ReportEmitErrorSummary = (errorCount: number, filesInError: (string | undefined)[]) => void;
8080

8181
export interface SolutionBuilderHostBase<T extends BuilderProgram> extends ProgramHost<T> {
8282
createDirectory?(path: string): void;
@@ -2002,10 +2002,12 @@ namespace ts {
20022002
const canReportSummary = state.watch || !!state.host.reportErrorSummary;
20032003
const { diagnostics } = state;
20042004
let totalErrors = 0;
2005+
let filesInError: (string | undefined)[] = [];
20052006
if (isCircularBuildOrder(buildOrder)) {
20062007
reportBuildQueue(state, buildOrder.buildOrder);
20072008
reportErrors(state, buildOrder.circularDiagnostics);
20082009
if (canReportSummary) totalErrors += getErrorCountForSummary(buildOrder.circularDiagnostics);
2010+
if (canReportSummary) filesInError = [...filesInError, ...getFilesInErrorForSummary(buildOrder.circularDiagnostics)];
20092011
}
20102012
else {
20112013
// Report errors from the other projects
@@ -2016,13 +2018,14 @@ namespace ts {
20162018
}
20172019
});
20182020
if (canReportSummary) diagnostics.forEach(singleProjectErrors => totalErrors += getErrorCountForSummary(singleProjectErrors));
2021+
if (canReportSummary) diagnostics.forEach(singleProjectErrors => [...filesInError, ...getFilesInErrorForSummary(singleProjectErrors)]);
20192022
}
20202023

20212024
if (state.watch) {
20222025
reportWatchStatus(state, getWatchErrorSummaryDiagnosticMessage(totalErrors), totalErrors);
20232026
}
20242027
else if (state.host.reportErrorSummary) {
2025-
state.host.reportErrorSummary(totalErrors);
2028+
state.host.reportErrorSummary(totalErrors, filesInError);
20262029
}
20272030
}
20282031

src/compiler/watch.ts

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace ts {
77
} : undefined;
88

99
/**
10-
* Create a function that reports error by writing to the system and handles the formating of the diagnostic
10+
* Create a function that reports error by writing to the system and handles the formatting of the diagnostic
1111
*/
1212
export function createDiagnosticReporter(system: System, pretty?: boolean): DiagnosticReporter {
1313
const host: FormatDiagnosticsHost = system === sys && sysFormatDiagnosticsHost ? sysFormatDiagnosticsHost : {
@@ -101,15 +101,51 @@ namespace ts {
101101
return countWhere(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error);
102102
}
103103

104+
export function getFilesInErrorForSummary(diagnostics: readonly Diagnostic[]) {
105+
return filter(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error)
106+
.map(
107+
errorDiagnostic => {
108+
if(errorDiagnostic.file === undefined) return;
109+
return `${errorDiagnostic.file.fileName}`;
110+
})
111+
.filter((value, index, self) => self !== undefined && self.indexOf(value) === index)
112+
.map((fileName: string) => {
113+
const diagnosticForFileName = find(diagnostics, diagnostic =>
114+
diagnostic.file !== undefined && diagnostic.file.fileName === fileName
115+
);
116+
117+
if(diagnosticForFileName !== undefined) {
118+
const { line } = getLineAndCharacterOfPosition(diagnosticForFileName.file!, diagnosticForFileName.start!);
119+
return `${fileName}:${line + 1}`;
120+
}
121+
});
122+
}
123+
104124
export function getWatchErrorSummaryDiagnosticMessage(errorCount: number) {
105125
return errorCount === 1 ?
106126
Diagnostics.Found_1_error_Watching_for_file_changes :
107127
Diagnostics.Found_0_errors_Watching_for_file_changes;
108128
}
109129

110-
export function getErrorSummaryText(errorCount: number, newLine: string) {
130+
export function getErrorSummaryText(
131+
errorCount: number,
132+
filesInError: readonly (string | undefined)[],
133+
newLine: string
134+
) {
111135
if (errorCount === 0) return "";
112-
const d = createCompilerDiagnostic(errorCount === 1 ? Diagnostics.Found_1_error : Diagnostics.Found_0_errors, errorCount);
136+
const d = errorCount === 1 ?
137+
createCompilerDiagnostic(
138+
filesInError[0] !== undefined ?
139+
Diagnostics.Found_1_error_in_1 :
140+
Diagnostics.Found_1_error,
141+
errorCount,
142+
filesInError[0]) :
143+
createCompilerDiagnostic(
144+
filesInError.length === 1 ?
145+
Diagnostics.Found_0_errors_in_1_file :
146+
Diagnostics.Found_0_errors_in_1_files,
147+
errorCount,
148+
filesInError.length);
113149
return `${newLine}${flattenDiagnosticMessageText(d.messageText, newLine)}${newLine}${newLine}`;
114150
}
115151

@@ -350,7 +386,7 @@ namespace ts {
350386
}
351387

352388
if (reportSummary) {
353-
reportSummary(getErrorCountForSummary(diagnostics));
389+
reportSummary(getErrorCountForSummary(diagnostics), getFilesInErrorForSummary(diagnostics));
354390
}
355391

356392
return {
@@ -656,7 +692,7 @@ namespace ts {
656692
builderProgram,
657693
input.reportDiagnostic || createDiagnosticReporter(system),
658694
s => host.trace && host.trace(s),
659-
input.reportErrorSummary || input.options.pretty ? errorCount => system.write(getErrorSummaryText(errorCount, system.newLine)) : undefined
695+
input.reportErrorSummary || input.options.pretty ? (errorCount, filesInError) => system.write(getErrorSummaryText(errorCount, filesInError, system.newLine)) : undefined
660696
);
661697
if (input.afterProgramEmitAndDiagnostics) input.afterProgramEmitAndDiagnostics(builderProgram);
662698
return exitStatus;

src/executeCommandLine/executeCommandLine.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ namespace ts {
749749

750750
function createReportErrorSummary(sys: System, options: CompilerOptions | BuildOptions): ReportEmitErrorSummary | undefined {
751751
return shouldBePretty(sys, options) ?
752-
errorCount => sys.write(getErrorSummaryText(errorCount, sys.newLine)) :
752+
(errorCount, filesInError) => sys.write(getErrorSummaryText(errorCount, filesInError, sys.newLine)) :
753753
undefined;
754754
}
755755

src/harness/harnessIO.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ namespace Harness {
536536
outputLines += content;
537537
}
538538
if (pretty) {
539-
outputLines += ts.getErrorSummaryText(ts.getErrorCountForSummary(diagnostics), IO.newLine());
539+
outputLines += ts.getErrorSummaryText(ts.getErrorCountForSummary(diagnostics), ts.getFilesInErrorForSummary(diagnostics), IO.newLine());
540540
}
541541
return outputLines;
542542
}

src/testRunner/unittests/tsbuild/publicApi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export function f22() { } // trailing`,
5454
/*createProgram*/ undefined,
5555
createDiagnosticReporter(sys, /*pretty*/ true),
5656
createBuilderStatusReporter(sys, /*pretty*/ true),
57-
errorCount => sys.write(getErrorSummaryText(errorCount, sys.newLine))
57+
(errorCount, filesInError) => sys.write(getErrorSummaryText(errorCount, filesInError, sys.newLine))
5858
);
5959
buildHost.afterProgramEmitAndDiagnostics = cb;
6060
buildHost.afterEmitBundle = cb;

src/testRunner/unittests/tscWatch/helpers.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,18 @@ namespace ts.tscWatch {
204204
assert.equal(host.exitCode, expectedExitCode);
205205
}
206206

207-
export function checkNormalBuildErrors(host: WatchedSystem, errors: readonly Diagnostic[] | readonly string[], reportErrorSummary?: boolean) {
207+
export function checkNormalBuildErrors(
208+
host: WatchedSystem,
209+
errors: readonly Diagnostic[] | readonly string[],
210+
files: readonly string[],
211+
reportErrorSummary?: boolean
212+
) {
208213
checkOutputErrors(
209214
host,
210215
[
211216
...map(errors, hostOutputDiagnostic),
212217
...reportErrorSummary ?
213-
[hostOutputWatchDiagnostic(getErrorSummaryText(errors.length, host.newLine))] :
218+
[hostOutputWatchDiagnostic(getErrorSummaryText(errors.length, files, host.newLine))] :
214219
emptyArray
215220
]
216221
);

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5249,7 +5249,7 @@ declare namespace ts {
52495249
traceResolution?: boolean;
52505250
[option: string]: CompilerOptionsValue | undefined;
52515251
}
5252-
type ReportEmitErrorSummary = (errorCount: number) => void;
5252+
type ReportEmitErrorSummary = (errorCount: number, filesInError: (string | undefined)[]) => void;
52535253
interface SolutionBuilderHostBase<T extends BuilderProgram> extends ProgramHost<T> {
52545254
createDirectory?(path: string): void;
52555255
/**

tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5249,7 +5249,7 @@ declare namespace ts {
52495249
traceResolution?: boolean;
52505250
[option: string]: CompilerOptionsValue | undefined;
52515251
}
5252-
type ReportEmitErrorSummary = (errorCount: number) => void;
5252+
type ReportEmitErrorSummary = (errorCount: number, filesInError: (string | undefined)[]) => void;
52535253
interface SolutionBuilderHostBase<T extends BuilderProgram> extends ProgramHost<T> {
52545254
createDirectory?(path: string): void;
52555255
/**

tests/baselines/reference/deeplyNestedAssignabilityIssue.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,5 @@
6565
}
6666
}
6767

68-
Found 2 errors.
68+
Found 2 errors in 1 file.
6969

tests/baselines/reference/duplicateIdentifierRelatedSpans1.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,5 @@
9292
!!! error TS2451: Cannot redeclare block-scoped variable 'Bar'.
9393
!!! related TS6203 tests/cases/compiler/file1.ts:2:7: 'Bar' was also declared here.
9494

95-
Found 6 errors.
95+
Found 6 errors in 3 files.
9696

tests/baselines/reference/duplicateIdentifierRelatedSpans2.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,5 @@
4545
class H { }
4646
class I { }
4747

48-
Found 2 errors.
48+
Found 2 errors in 2 files.
4949

tests/baselines/reference/duplicateIdentifierRelatedSpans3.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,5 @@
8585
!!! related TS6203 tests/cases/compiler/file1.ts:4:5: 'duplicate3' was also declared here.
8686
}
8787

88-
Found 6 errors.
88+
Found 6 errors in 2 files.
8989

tests/baselines/reference/duplicateIdentifierRelatedSpans4.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,5 @@
4747
duplicate8(): number;
4848
}
4949

50-
Found 2 errors.
50+
Found 2 errors in 2 files.
5151

tests/baselines/reference/duplicateIdentifierRelatedSpans5.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,5 @@
9292
}
9393
export {}
9494

95-
Found 6 errors.
95+
Found 6 errors in 2 files.
9696

tests/baselines/reference/duplicateIdentifierRelatedSpans6.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,5 @@
9292
!!! related TS6203 tests/cases/compiler/file2.ts:7:9: 'duplicate3' was also declared here.
9393
}
9494
}
95-
Found 6 errors.
95+
Found 6 errors in 2 files.
9696

tests/baselines/reference/duplicateIdentifierRelatedSpans7.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,5 @@
5656
duplicate9: () => string;
5757
}
5858
}
59-
Found 2 errors.
59+
Found 2 errors in 2 files.
6060

tests/baselines/reference/esModuleInteropPrettyErrorRelatedInformation.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@
2323
!!! error TS2345: Type '{ default: () => void; }' provides no match for the signature '(): void'.
2424
!!! related TS7038 tests/cases/compiler/index.ts:1:1: Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead.
2525

26-
Found 1 error.
26+
Found 1 error in tests/cases/compiler/index.ts:3
2727

tests/baselines/reference/multiLineContextDiagnosticWithPretty.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@
2121
!!! error TS2322: Object literal may only specify known properties, and 'a' does not exist in type '{ c: string; }'.
2222
};
2323

24-
Found 1 error.
24+
Found 1 error in tests/cases/compiler/multiLineContextDiagnosticWithPretty.ts:2
2525

tests/baselines/reference/prettyContextNotDebugAssertion.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515

1616
!!! error TS1005: '}' expected.
1717
!!! related TS1007 tests/cases/compiler/index.ts:1:11: The parser expected to find a '}' to match the '{' token here.
18-
Found 1 error.
18+
Found 1 error in tests/cases/compiler/index.ts:2
1919

tests/baselines/reference/prettyFileWithErrorsAndTabs.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@
2626
!!! error TS2322: Type 'number' is not assignable to type 'string'.
2727
}
2828
}
29-
Found 3 errors.
29+
Found 3 errors in 1 file.
3030

tests/baselines/reference/tsbuild/configFileErrors/initial-build/when-tsconfig-extends-the-missing-file.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Output::
4242
error TS18003: No inputs were found in config file '/src/tsconfig.second.json'. Specified 'include' paths were '["**/*"]' and 'exclude' paths were '[]'.
4343

4444

45-
Found 4 errors.
45+
Found 4 errors in 0 files.
4646

4747
exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped
4848

tests/baselines/reference/tsbuild/demo/initial-build/in-bad-ref-branch-reports-the-error-about-files-not-in-rootDir-at-the-import-location.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ Output::
208208
[12:00:00 AM] Skipping build of project '/src/zoo/tsconfig.json' because its dependency '/src/animals' was not built
209209

210210

211-
Found 7 errors.
211+
Found 7 errors in 0 files.
212212

213213
exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped
214214

tests/baselines/reference/tsc/composite/initial-build/when-setting-composite-false-on-command-line-but-has-tsbuild-info-in-config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Output::
4040
   ~~~~~~~~~~~~~~~~~
4141

4242

43-
Found 1 error.
43+
Found 1 error in src/project/tsconfig.json:6
4444

4545
exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated
4646

tests/baselines/reference/tsc/declarationEmit/when-pkg-references-sibling-package-through-indirect-symlink-moduleCaseChange.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pkg3/src/keys.ts
7878
pkg3/src/index.ts
7979
Matched by include pattern '**/*' in 'pkg3/tsconfig.json'
8080

81-
Found 1 error.
81+
Found 1 error in /user/username/projects/myproject/pkg3/src/keys.ts:2
8282

8383

8484

tests/baselines/reference/tsc/declarationEmit/when-pkg-references-sibling-package-through-indirect-symlink.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pkg3/src/keys.ts
7878
pkg3/src/index.ts
7979
Matched by include pattern '**/*' in 'pkg3/tsconfig.json'
8080

81-
Found 1 error.
81+
Found 1 error in /user/username/projects/myproject/pkg3/src/keys.ts:2
8282

8383

8484

0 commit comments

Comments
 (0)