From 5a8b2ccda4be044af1d438e9d8e469c7d26162d6 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Tue, 30 Jul 2024 14:18:47 -0700 Subject: [PATCH] Keep watch going when crash happens (#4022) fix [#2263](https://github.com/microsoft/typespec/issues/2263) --- ...ernal-compiler-error-2024-6-25-21-39-16.md | 8 ++++++ .../src/core/cli/actions/compile/compile.ts | 24 +++++++++++------ packages/compiler/src/core/cli/utils.ts | 26 ++++++++++--------- 3 files changed, 38 insertions(+), 20 deletions(-) create mode 100644 .chronus/changes/keep-watch-internal-compiler-error-2024-6-25-21-39-16.md diff --git a/.chronus/changes/keep-watch-internal-compiler-error-2024-6-25-21-39-16.md b/.chronus/changes/keep-watch-internal-compiler-error-2024-6-25-21-39-16.md new file mode 100644 index 0000000000..eb93d0bcd3 --- /dev/null +++ b/.chronus/changes/keep-watch-internal-compiler-error-2024-6-25-21-39-16.md @@ -0,0 +1,8 @@ +--- +# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking +changeKind: fix +packages: + - "@typespec/compiler" +--- + +`tsp compile --watch` will not stop when a crash happens during compilation diff --git a/packages/compiler/src/core/cli/actions/compile/compile.ts b/packages/compiler/src/core/cli/actions/compile/compile.ts index acd03fadfa..5b634aa64c 100644 --- a/packages/compiler/src/core/cli/actions/compile/compile.ts +++ b/packages/compiler/src/core/cli/actions/compile/compile.ts @@ -6,7 +6,11 @@ import { resolvePath } from "../../../path-utils.js"; import { Program, compile as compileProgram } from "../../../program.js"; import { CompilerHost, Diagnostic } from "../../../types.js"; import { CliCompilerHost } from "../../types.js"; -import { handleInternalCompilerError, logDiagnosticCount } from "../../utils.js"; +import { + handleInternalCompilerError, + logDiagnosticCount, + logInternalCompilerError, +} from "../../utils.js"; import { CompileCliArgs, getCompilerOptions } from "./args.js"; import { ProjectWatcher, WatchHost, createWatchHost, createWatcher } from "./watch.js"; @@ -77,10 +81,11 @@ function compileWatch( path: string, compilerOptions: CompilerOptions ): Promise { + const entrypoint = resolve(path); const watchHost: WatchHost = createWatchHost(cliHost); let compileRequested: boolean = false; - let currentCompilePromise: Promise | undefined = undefined; + let currentCompilePromise: Promise | undefined = undefined; const runCompilePromise = () => { // Don't run the compiler if it's already running @@ -90,9 +95,9 @@ function compileWatch( console.clear(); watchHost?.forceJSReload(); - currentCompilePromise = compileProgram(watchHost, resolve(path), compilerOptions) - .then(onCompileFinished) - .catch(handleInternalCompilerError); + currentCompilePromise = compileProgram(watchHost, entrypoint, compilerOptions) + .catch(logInternalCompilerError) + .then(onCompileFinished); } else { compileRequested = true; } @@ -105,10 +110,13 @@ function compileWatch( const watcher: ProjectWatcher = createWatcher((_name: string) => { scheduleCompile(); }); + watcher?.updateWatchedFiles([entrypoint]); - const onCompileFinished = (program: Program) => { - watcher?.updateWatchedFiles([...program.sourceFiles.keys(), ...program.jsSourceFiles.keys()]); - logProgramResult(watchHost, program, { showTimestamp: true }); + const onCompileFinished = (program?: Program | void) => { + if (program !== undefined) { + watcher?.updateWatchedFiles([...program.sourceFiles.keys(), ...program.jsSourceFiles.keys()]); + logProgramResult(watchHost, program, { showTimestamp: true }); + } currentCompilePromise = undefined; if (compileRequested) { diff --git a/packages/compiler/src/core/cli/utils.ts b/packages/compiler/src/core/cli/utils.ts index 089a6f6bab..6ac6326aa3 100644 --- a/packages/compiler/src/core/cli/utils.ts +++ b/packages/compiler/src/core/cli/utils.ts @@ -142,17 +142,7 @@ export function logDiagnosticCount(diagnostics: readonly Diagnostic[]) { console.log(`\nFound ${[errorText, warningText].filter((x) => x !== undefined).join(", ")}.`); } -/** - * Handle an internal compiler error. - * - * NOTE: An expected error, like one thrown for bad input, shouldn't reach - * here, but be handled somewhere else. If we reach here, it should be - * considered a bug and therefore we should not suppress the stack trace as - * that risks losing it in the case of a bug that does not repro easily. - * - * @param error error thrown - */ -export function handleInternalCompilerError(error: unknown): never { +export function logInternalCompilerError(error: unknown) { /* eslint-disable no-console */ if (error instanceof ExternalError) { // ExternalError should already have all the relevant information needed when thrown. @@ -164,7 +154,19 @@ export function handleInternalCompilerError(error: unknown): never { console.error(error); } /* eslint-enable no-console */ - +} +/** + * Handle an internal compiler error. + * + * NOTE: An expected error, like one thrown for bad input, shouldn't reach + * here, but be handled somewhere else. If we reach here, it should be + * considered a bug and therefore we should not suppress the stack trace as + * that risks losing it in the case of a bug that does not repro easily. + * + * @param error error thrown + */ +export function handleInternalCompilerError(error: unknown) { + logInternalCompilerError(error); process.exit(1); }