Skip to content

Commit

Permalink
Format diagnostics with the compiler's tools; limit to 3 diagnostics;…
Browse files Browse the repository at this point in the history
… add tests
  • Loading branch information
timostamm committed Oct 31, 2024
1 parent 9e0abff commit 7e17860
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,66 @@ describe("built-in transpile", () => {
]);
});
});

describe("failing to emit", () => {
test("raises error with helpful message", async () => {
await expect(async () =>
testTranspileToDts([
`export interface Foo {`,
` p: {`,
` [K in keyof P]: string;`,
` },`,
`}`,
]),
).rejects.toThrow(
/^A problem occurred during transpilation and files were not generated\. {2}Contact the plugin author for support\.\n/,
);
});
test("raises error with diagnostics", async () => {
await expect(async () =>
testTranspileToDts([
`export interface Foo {`,
` p: {`,
` [K in keyof P]: string;`,
` },`,
`}`,
]),
).rejects.toThrow(
/test\.ts\(3,17\): error TS4033: Property 'p' of exported interface has or is using private name 'P'\.$/,
);
});
test("raises error with 3 diagnostics, and elides the rest", async () => {
await expect(async () =>
testTranspileToDts([
`export interface Foo1 {`,
` p: {`,
` [K in keyof P]: string;`,
` },`,
`}`,
`export interface Foo2 {`,
` p: {`,
` [K in keyof P]: string;`,
` },`,
`}`,
`export interface Foo3 {`,
` p: {`,
` [K in keyof P]: string;`,
` },`,
`}`,
`export interface Foo4 {`,
` p: {`,
` [K in keyof P]: string;`,
` },`,
`}`,
`export interface Foo5 {`,
` p: {`,
` [K in keyof P]: string;`,
` },`,
`}`,
]),
).rejects.toThrow(
/(?:test\.ts\(\d+,\d+\): .+\n){3}2 more diagnostics elided/,
);
});
});
});
34 changes: 27 additions & 7 deletions packages/protoplugin/src/transpile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,35 @@ export function transpile(
throw err;
}
if (result.emitSkipped) {
const fileNames = files.map((f) => f.name).join("\n");
const diagnosticMessages = result.diagnostics
.map((d) => d.messageText)
.join("\n");

// When compilation fails, this error will be shown in the results of the NPM install error log.
// When compilation fails, this error message is printed to stderr.
const diagnostics = formatDiagnostics(result.diagnostics);
throw Error(
`A problem occurred during transpilation and files were not generated. Contact the plugin author for support.\n\nGenerating Files:\n\n${fileNames}\n\nDiagnostics:\n\n${diagnosticMessages}`,
`A problem occurred during transpilation and files were not generated. Contact the plugin author for support.\n\n${diagnostics}`,
);
}
return results;
}

function formatDiagnostics(diagnostics: readonly ts.Diagnostic[]): string {
const sorted = ts.sortAndDeduplicateDiagnostics(diagnostics);
if (sorted.length == 0) {
return "";
}
const first = sorted.slice(0, 3);
const formatHost: ts.FormatDiagnosticsHost = {
getCanonicalFileName(fileName: string): string {
return fileName;
},
getCurrentDirectory(): string {
return ".";
},
getNewLine(): string {
return "\n";
},
};
let out = ts.formatDiagnostics(first, formatHost).trim();
if (first.length < sorted.length) {
out += `\n${sorted.length - first.length} more diagnostics elided`;
}
return out;
}

0 comments on commit 7e17860

Please sign in to comment.