mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 10:06:21 +00:00
feat(cli): report command failure reasons to telemetry (de-blind browser/info) (#1484)
Observability showed `browser` (~75% fail, ~1.3k users/day) and `info` (~60% fail) failing at high rates with no captured reason — only `cli_command_result success=false`. citty's `runMain` catches a command's thrown error and `process.exit(1)`s without re-throwing, so a thrown failure never reached the existing `cli_error` telemetry (which only fired from the uncaughtException / unhandledRejection handlers). Wrap every command's `run()` at the dispatch boundary (cli.ts) so a thrown failure reports its reason via `cli_error` (kind=command_error) before being re-thrown unchanged — citty's print + exit-1 behavior is preserved. This de-blinds every throw-style command at once: `browser ensure` (Chrome download), `tts`, `inspect`, `render`, etc. Paths that bypass the wrapper are handled inline: - `browser` self-exits (`path` download failure, unknown subcommand) — report inline; the ARM64 `ensure` branch previously swallowed a failed install and returned success, now reports and exits 1. - `resolveProject()` self-exits on InvalidProjectError (the dominant `info` failure — run outside a project) — report inline before exit. Hardening: - PII: `trackCliError` now redacts error_message + stack_trace via redactTelemetryString (matching render_* events) — CLI errors and stacks carry absolute install paths / cache dirs / user args. - Race: the wrapper awaits an on-demand telemetry import before re-throwing, so a command that fails before the lazy telemetry import settles still reports (a telemetry failure is swallowed and never masks the real error). Pure helpers in utils/command-failure-tracking.ts with unit tests for the throw / success / no-run / onFailure-rejection cases, the reporter wiring, and trackCliError redaction. CommandDef<any> mirrors citty's SubCommandsDef. Known scope: commands that print + `process.exit(1)` on their own validation paths (tts/validate/lint argument errors) remain wrapper-blind — follow-up.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { existsSync, statSync } from "node:fs";
|
||||
import { resolve, basename } from "node:path";
|
||||
import { errorBox } from "../ui/format.js";
|
||||
import { trackCommandFailure } from "../telemetry/events.js";
|
||||
|
||||
export interface ProjectDir {
|
||||
dir: string;
|
||||
@@ -55,6 +56,11 @@ export function resolveProject(dirArg: string | undefined): ProjectDir {
|
||||
return resolveProjectOrThrow(dirArg);
|
||||
} catch (err) {
|
||||
if (err instanceof InvalidProjectError) {
|
||||
// Self-exit (not a throw) so the cli.ts wrapper never sees it — report
|
||||
// inline. argv[2] is the running command (info / inspect / render / ...).
|
||||
// This is the dominant failure for read-only commands like `info` run
|
||||
// outside a project; the redaction in trackCliError strips the dir path.
|
||||
trackCommandFailure(process.argv[2] ?? "unknown", err);
|
||||
errorBox(err.title, err.hint, err.suggestion);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user