From 5af253283e2c5db670be1ef671d0ad88e094b72e Mon Sep 17 00:00:00 2001 From: nokeo08 Date: Wed, 17 Jun 2026 16:32:29 -0500 Subject: [PATCH] Introduce failRuntime() to mirror failUser() in move.ts The two stderr-fatal paths used to be asymmetric: failUser() is a named helper with 'move:' prefix and a 'Try --help' hint, while the runKeeper catch was an inline 'console.error("Error:", err)' + process.exit(1). failRuntime() now sits next to failUser(), so the entry-point reads as 'one of two well-named fatal paths.' It also prefers err.stack when available, giving better diagnostics for nut.js / Accessibility-permission failures than the previous formatter. Same observable behavior on the success path; failure messages on the runtime path are now more debuggable. --- src/move.ts | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/move.ts b/src/move.ts index ef9c2ab..39ef3fd 100755 --- a/src/move.ts +++ b/src/move.ts @@ -32,8 +32,13 @@ import { loadConfigFile } from "./configFile.ts"; import { runKeeper } from "./keeper.ts"; /** - * Print a CLI-style error and exit 2. Returns `never` so callers can use - * it without TypeScript flagging "variable might be undefined" downstream. + * Print a user-error message and exit 2. Used for anything that comes from + * invalid input: unknown CLI flags, bad numbers, malformed or missing + * config files, unresolvable default paths. The accompanying "Try 'move + * --help'" pointer is appropriate for these cases. + * + * Returns `never` so callers can invoke it without TypeScript flagging + * "variable might be undefined" downstream. */ function failUser(err: unknown): never { const msg: string = err instanceof Error ? err.message : String(err); @@ -41,6 +46,19 @@ function failUser(err: unknown): never { process.exit(2); } +/** + * Print a runtime-failure message and exit 1. Used for anything the user + * couldn't have prevented from the command line: nut.js errors, missing + * Accessibility permission on macOS, unexpected exceptions from the + * keeper loop. Prefers the stack trace when available since these failures + * usually need a developer to interpret. + */ +function failRuntime(err: unknown): never { + const detail: string = err instanceof Error ? (err.stack ?? err.message) : String(err); + process.stderr.write(`move: runtime error: ${detail}\n`); + process.exit(1); +} + let cliArgs: ParsedCliArgs; try { cliArgs = parseCliArgs(); @@ -80,7 +98,4 @@ const cliOverrides: ConfigOverrides = { const config = resolveConfig(fileOverrides, cliOverrides); -runKeeper(config).catch((err: unknown): void => { - console.error("Error:", err); - process.exit(1); -}); +runKeeper(config).catch(failRuntime);