Skip to content

Commit b0ba301

Browse files
committed
chore(cli): wrap third-party errors (get-port, latest-version, inquirer, stream-json) in CliError
- getLatestVersionOfCli: catch PackageNotFoundError/SyntaxError from latest-version, rethrow as CliError(NETWORK_ERROR) - CliContext.getInput: catch ExitPromptError from @inquirer/prompts, convert to TaskAbortSignal (matches confirmPrompt behavior) - cli.ts docs dev: catch SystemError from get-port, rethrow as CliError(ENVIRONMENT_ERROR) - diff.ts readIr: catch stream-json parser errors from streamObjectFromFile, report as CliError(PARSE_ERROR) Made-with: Cursor
1 parent a1e5e34 commit b0ba301

4 files changed

Lines changed: 51 additions & 16 deletions

File tree

packages/cli/cli/src/cli-context/CliContext.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,15 @@ export class CliContext {
457457
* @returns Promise<string> representing the user's input
458458
*/
459459
public async getInput(config: { message: string; default?: string }): Promise<string> {
460-
return await input({ message: config.message, default: config.default });
460+
try {
461+
return await input({ message: config.message, default: config.default });
462+
} catch (error) {
463+
if ((error as Error)?.name === "ExitPromptError") {
464+
this.logger.info("\nCancelled by user.");
465+
throw new TaskAbortSignal();
466+
}
467+
throw error;
468+
}
461469
}
462470
}
463471

packages/cli/cli/src/cli-context/upgrade-utils/getLatestVersionOfCli.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { CliError } from "@fern-api/task-context";
12
import latestVersion from "latest-version";
23

34
import { CliEnvironment } from "../CliEnvironment.js";
@@ -14,7 +15,14 @@ export async function getLatestVersionOfCli({
1415
if (cliEnvironment.packageName !== "fern-api" || cliEnvironment.packageVersion === "0.0.0") {
1516
return cliEnvironment.packageVersion;
1617
}
17-
return latestVersion(cliEnvironment.packageName, {
18-
version: includePreReleases ? "prerelease" : "latest"
19-
});
18+
try {
19+
return await latestVersion(cliEnvironment.packageName, {
20+
version: includePreReleases ? "prerelease" : "latest"
21+
});
22+
} catch (error) {
23+
throw new CliError({
24+
message: `Failed to resolve latest CLI version: ${error instanceof Error ? error.message : String(error)}`,
25+
code: "NETWORK_ERROR"
26+
});
27+
}
2028
}

packages/cli/cli/src/cli.ts

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1903,18 +1903,27 @@ function addDocsDevCommand(cli: Argv<GlobalCliOptions>, cliContext: CliContext)
19031903
}
19041904

19051905
let port: number;
1906-
if (argv.port != null) {
1907-
port = argv.port;
1908-
} else {
1909-
port = await getPort({ port: [3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010] });
1910-
}
1911-
19121906
let backendPort: number;
1913-
if (argv.backendPort != null) {
1914-
backendPort = argv.backendPort;
1915-
} else {
1916-
backendPort = await getPort({
1917-
port: [3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011]
1907+
try {
1908+
if (argv.port != null) {
1909+
port = argv.port;
1910+
} else {
1911+
port = await getPort({
1912+
port: [3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010]
1913+
});
1914+
}
1915+
1916+
if (argv.backendPort != null) {
1917+
backendPort = argv.backendPort;
1918+
} else {
1919+
backendPort = await getPort({
1920+
port: [3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011]
1921+
});
1922+
}
1923+
} catch (error) {
1924+
throw new CliError({
1925+
message: `Failed to find an available port: ${error instanceof Error ? error.message : String(error)}`,
1926+
code: "ENVIRONMENT_ERROR"
19181927
});
19191928
}
19201929
const bundlePath: string | undefined = argv.bundlePath;

packages/cli/cli/src/commands/diff/diff.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,17 @@ async function readIr({
7676
context.failWithoutThrowing(`File not found: ${absoluteFilepath}`, undefined, { code: "CONFIG_ERROR" });
7777
throw new TaskAbortSignal();
7878
}
79-
const ir = await streamObjectFromFile(absoluteFilepath);
79+
let ir: unknown;
80+
try {
81+
ir = await streamObjectFromFile(absoluteFilepath);
82+
} catch (error) {
83+
context.failWithoutThrowing(
84+
`Failed to parse IR file ${absoluteFilepath}: ${error instanceof Error ? error.message : String(error)}`,
85+
error,
86+
{ code: "PARSE_ERROR" }
87+
);
88+
throw new TaskAbortSignal();
89+
}
8090
const parsed = serialization.IntermediateRepresentation.parse(ir);
8191
if (!parsed.ok) {
8292
context.failWithoutThrowing(`Invalid --${flagName}; expected a filepath containing a valid IR`, undefined, {

0 commit comments

Comments
 (0)