Skip to content

Commit 55ea24d

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 2de3fdd commit 55ea24d

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
@@ -458,7 +458,15 @@ export class CliContext {
458458
* @returns Promise<string> representing the user's input
459459
*/
460460
public async getInput(config: { message: string; default?: string }): Promise<string> {
461-
return await input({ message: config.message, default: config.default });
461+
try {
462+
return await input({ message: config.message, default: config.default });
463+
} catch (error) {
464+
if ((error as Error)?.name === "ExitPromptError") {
465+
this.logger.info("\nCancelled by user.");
466+
throw new TaskAbortSignal();
467+
}
468+
throw error;
469+
}
462470
}
463471
}
464472

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
@@ -1906,18 +1906,27 @@ function addDocsDevCommand(cli: Argv<GlobalCliOptions>, cliContext: CliContext)
19061906
}
19071907

19081908
let port: number;
1909-
if (argv.port != null) {
1910-
port = argv.port;
1911-
} else {
1912-
port = await getPort({ port: [3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010] });
1913-
}
1914-
19151909
let backendPort: number;
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]
1910+
try {
1911+
if (argv.port != null) {
1912+
port = argv.port;
1913+
} else {
1914+
port = await getPort({
1915+
port: [3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010]
1916+
});
1917+
}
1918+
1919+
if (argv.backendPort != null) {
1920+
backendPort = argv.backendPort;
1921+
} else {
1922+
backendPort = await getPort({
1923+
port: [3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011]
1924+
});
1925+
}
1926+
} catch (error) {
1927+
throw new CliError({
1928+
message: `Failed to find an available port: ${error instanceof Error ? error.message : String(error)}`,
1929+
code: "ENVIRONMENT_ERROR"
19211930
});
19221931
}
19231932
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)