From 5b138df664a3ab7cb63480e8b1c8988e820938b1 Mon Sep 17 00:00:00 2001 From: mitchell Date: Fri, 19 Jun 2026 14:33:56 -0400 Subject: [PATCH] refactor(errors): extract isErrorLike and use ExecaError class in tts --- src/errors.ts | 17 +++++++++++------ src/tts.ts | 4 ++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/errors.ts b/src/errors.ts index a8e9e05..2eac281 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,13 +1,18 @@ import { chalkStderr } from "chalk"; import wrapAnsi from "wrap-ansi"; +export interface ErrorLike { + message: string; +} + +export const isErrorLike = (err: unknown): err is ErrorLike => + typeof err === "object" && + err !== null && + "message" in err && + typeof err.message === "string"; + export function handleTopLevel(err: unknown) { - if ( - typeof err === "object" && - err !== null && - "message" in err && - typeof err.message === "string" - ) { + if (isErrorLike(err)) { if (process.stderr.isTTY) { const [columns] = process.stderr.getWindowSize(); console.error(wrapAnsi(chalkStderr.red(err.message), columns)); diff --git a/src/tts.ts b/src/tts.ts index 75f37b1..4e8c36c 100644 --- a/src/tts.ts +++ b/src/tts.ts @@ -8,7 +8,7 @@ import consumers from "node:stream/consumers"; import util from "node:util"; import { Readability } from "@mozilla/readability"; import chalk from "chalk"; -import { execa } from "execa"; +import { ExecaError, execa } from "execa"; import { Window } from "happy-dom"; import wrapAnsi from "wrap-ansi"; import { handleTopLevel } from "./errors"; @@ -151,7 +151,7 @@ async function main() { try { await execa({ cwd, shell: true })`sox ${files} output.wav`; } catch (err) { - if (err instanceof Object && "code" in err && err.code === "ENOENT") { + if (err instanceof ExecaError && err.code === "ENOENT") { console.error("Sox not found. Unable to combine outputs."); console.log(chalk.yellow(`Audio available in ${cwd}`)); return;