Skip to content

Commit 00ddca9

Browse files
committed
chore(cli): keep @fern-api/docker-utils as plain Error, add CONTAINER_ERROR wrappers at call sites
1 parent e2b941e commit 00ddca9

5 files changed

Lines changed: 70 additions & 25 deletions

File tree

packages/cli/generation/local-generation/local-workspace-runner/src/ContainerExecutionEnvironment.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ContainerRunner } from "@fern-api/core-utils";
22
import { runContainer } from "@fern-api/docker-utils";
3+
import { CliError } from "@fern-api/task-context";
34
import {
45
CONTAINER_CODEGEN_OUTPUT_DIRECTORY,
56
CONTAINER_GENERATOR_CONFIG_PATH,
@@ -79,15 +80,25 @@ export class ContainerExecutionEnvironment implements ExecutionEnvironment {
7980
ports[DEFAULT_NODE_DEBUG_PORT] = DEFAULT_NODE_DEBUG_PORT;
8081
}
8182

82-
await runContainer({
83-
logger: context.logger,
84-
imageName: this.containerImage,
85-
args: [CONTAINER_GENERATOR_CONFIG_PATH],
86-
binds,
87-
envVars,
88-
ports,
89-
removeAfterCompletion: !this.keepContainer,
90-
runner: this.runner ?? runner
91-
});
83+
try {
84+
await runContainer({
85+
logger: context.logger,
86+
imageName: this.containerImage,
87+
args: [CONTAINER_GENERATOR_CONFIG_PATH],
88+
binds,
89+
envVars,
90+
ports,
91+
removeAfterCompletion: !this.keepContainer,
92+
runner: this.runner ?? runner
93+
});
94+
} catch (error) {
95+
if (error instanceof CliError) {
96+
throw error;
97+
}
98+
throw new CliError({
99+
message: `Container execution failed: ${error instanceof Error ? error.message : String(error)}`,
100+
code: CliError.Code.ContainerError
101+
});
102+
}
92103
}
93104
}

packages/cli/generation/local-generation/local-workspace-runner/src/GenerationRunner.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { generatorsYml, SNIPPET_JSON_FILENAME } from "@fern-api/configuration";
44
import { AbsoluteFilePath, join, RelativeFilePath } from "@fern-api/fs-utils";
55
import { generateIntermediateRepresentation } from "@fern-api/ir-generator";
66
import { IntermediateRepresentation } from "@fern-api/ir-sdk";
7-
import { TaskAbortSignal, TaskContext } from "@fern-api/task-context";
7+
import { CliError, TaskAbortSignal, TaskContext } from "@fern-api/task-context";
88
import { FernGeneratorExec } from "@fern-fern/generator-exec-sdk";
99
import chalk from "chalk";
1010
import { generateDynamicSnippetTests } from "./dynamic-snippets/generateDynamicSnippetTests.js";
@@ -57,7 +57,9 @@ export class GenerationRunner {
5757
async (interactiveTaskContext) => {
5858
if (generatorInvocation.absolutePathToLocalOutput == null) {
5959
interactiveTaskContext.failWithoutThrowing(
60-
"Cannot generate because output location is not local-file-system"
60+
"Cannot generate because output location is not local-file-system",
61+
undefined,
62+
{ code: CliError.Code.ConfigError }
6163
);
6264
return;
6365
}
@@ -104,7 +106,8 @@ export class GenerationRunner {
104106
} else {
105107
interactiveTaskContext.failWithoutThrowing(
106108
`Generation failed: ${error instanceof Error ? error.message : "Unknown error"}`,
107-
error
109+
error,
110+
{ code: CliError.Code.InternalError }
108111
);
109112
}
110113
}

packages/cli/generation/local-generation/local-workspace-runner/src/ReusableContainerExecutionEnvironment.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
} from "@fern-api/docker-utils";
99
import { Logger, LogLevel } from "@fern-api/logger";
1010
import { loggingExeca } from "@fern-api/logging-execa";
11+
import { CliError } from "@fern-api/task-context";
1112
import {
1213
CONTAINER_CODEGEN_OUTPUT_DIRECTORY,
1314
CONTAINER_FERN_DIRECTORY,
@@ -90,7 +91,13 @@ export class ReusableContainerExecutionEnvironment implements ExecutionEnvironme
9091
}
9192
this.containers = [];
9293
this.availableContainers = [];
93-
throw error;
94+
if (error instanceof CliError) {
95+
throw error;
96+
}
97+
throw new CliError({
98+
message: `Failed to start containers: ${error instanceof Error ? error.message : String(error)}`,
99+
code: CliError.Code.ContainerError
100+
});
94101
}
95102

96103
if (isDebug) {
@@ -108,6 +115,14 @@ export class ReusableContainerExecutionEnvironment implements ExecutionEnvironme
108115
const containerId = await this.acquire();
109116
try {
110117
await this.doExecute(containerId, args);
118+
} catch (error) {
119+
if (error instanceof CliError) {
120+
throw error;
121+
}
122+
throw new CliError({
123+
message: `Container execution failed: ${error instanceof Error ? error.message : String(error)}`,
124+
code: CliError.Code.ContainerError
125+
});
111126
} finally {
112127
this.release(containerId);
113128
}

packages/cli/generation/local-generation/local-workspace-runner/src/dynamic-snippets/java/DynamicSnippetsJavaTestGenerator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { AbsoluteFilePath, doesPathExist, join, RelativeFilePath } from "@fern-a
33
import { dynamic } from "@fern-api/ir-sdk";
44
import { Config, DynamicSnippetsGenerator } from "@fern-api/java-dynamic-snippets";
55
import { loggingExeca } from "@fern-api/logging-execa";
6-
import { TaskContext } from "@fern-api/task-context";
6+
import { CliError, TaskContext } from "@fern-api/task-context";
77
import { FernGeneratorExec } from "@fern-fern/generator-exec-sdk";
88
import { cp, mkdir, writeFile } from "fs/promises";
99
import path from "path";
@@ -101,7 +101,7 @@ export class DynamicSnippetsJavaTestGenerator {
101101
}
102102
}
103103
} catch (e) {
104-
this.context.failAndThrow("Failed to run spotlessApply", e);
104+
this.context.failAndThrow("Failed to run spotlessApply", e, { code: CliError.Code.InternalError });
105105
}
106106
}
107107
this.context.logger.debug("Done generating dynamic snippet tests");

packages/cli/generation/local-generation/local-workspace-runner/src/runLocalGenerationForWorkspace.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { generateIntermediateRepresentation } from "@fern-api/ir-generator";
1717
import { FernIr, PublishTarget } from "@fern-api/ir-sdk";
1818
import { OSSWorkspace } from "@fern-api/lazy-fern-workspace";
1919
import { getDynamicGeneratorConfig } from "@fern-api/remote-workspace-runner";
20-
import { TaskContext } from "@fern-api/task-context";
20+
import { CliError, TaskContext } from "@fern-api/task-context";
2121
import type { FernVenusApi } from "@fern-api/venus-api-sdk";
2222
import {
2323
AbstractAPIWorkspace,
@@ -109,7 +109,9 @@ export async function runLocalGenerationForWorkspace({
109109
{
110110
onError: (e) => {
111111
if (!isPreview && (requireEnvVars ?? true)) {
112-
interactiveTaskContext.failAndThrow(e);
112+
interactiveTaskContext.failAndThrow(e, undefined, {
113+
code: CliError.Code.ConfigError
114+
});
113115
}
114116
}
115117
},
@@ -172,7 +174,11 @@ export async function runLocalGenerationForWorkspace({
172174
if (generatorInvocation.absolutePathToLocalOutput == null) {
173175
token ??= await getAccessToken();
174176
if (token == null) {
175-
interactiveTaskContext.failWithoutThrowing("Please provide a FERN_TOKEN in your environment.");
177+
interactiveTaskContext.failWithoutThrowing(
178+
"Please provide a FERN_TOKEN in your environment.",
179+
undefined,
180+
{ code: CliError.Code.ConfigError }
181+
);
176182
return;
177183
}
178184
}
@@ -181,7 +187,9 @@ export async function runLocalGenerationForWorkspace({
181187

182188
if (generatorInvocation.absolutePathToLocalOutput == null && !organization.ok) {
183189
interactiveTaskContext.failWithoutThrowing(
184-
`Failed to load details for organization ${projectConfig.organization}.`
190+
`Failed to load details for organization ${projectConfig.organization}.`,
191+
undefined,
192+
{ code: CliError.Code.NetworkError }
185193
);
186194
return;
187195
}
@@ -237,7 +245,9 @@ export async function runLocalGenerationForWorkspace({
237245
` github:\n` +
238246
` uri: your-org/your-sdk-repo\n` +
239247
` token: \${GITHUB_TOKEN}\n` +
240-
` mode: pull-request\n`
248+
` mode: pull-request\n`,
249+
undefined,
250+
{ code: CliError.Code.ConfigError }
241251
);
242252
}
243253
}
@@ -291,15 +301,19 @@ export async function runLocalGenerationForWorkspace({
291301
if (!branchExists) {
292302
const parsedRepo = parseRepository(selfhostedGithubConfig.uri);
293303
interactiveTaskContext.failAndThrow(
294-
`Branch ${selfhostedGithubConfig.branch} does not exist in repository ${parsedRepo.owner}/${parsedRepo.repo}`
304+
`Branch ${selfhostedGithubConfig.branch} does not exist in repository ${parsedRepo.owner}/${parsedRepo.repo}`,
305+
undefined,
306+
{ code: CliError.Code.ConfigError }
295307
);
296308
}
297309
}
298310
await repo.checkoutRemoteBranch(selfhostedGithubConfig.branch);
299311
}
300312
} catch (error) {
301313
interactiveTaskContext.failAndThrow(
302-
`Failed to clone GitHub repository ${selfhostedGithubConfig.uri}: ${extractErrorMessage(error)}`
314+
`Failed to clone GitHub repository ${selfhostedGithubConfig.uri}: ${extractErrorMessage(error)}`,
315+
error,
316+
{ code: CliError.Code.NetworkError }
303317
);
304318
}
305319
}
@@ -424,7 +438,9 @@ export async function runLocalGenerationForWorkspace({
424438

425439
if (!pipelineResult.success) {
426440
interactiveTaskContext.failAndThrow(
427-
`Post-generation pipeline failed: ${pipelineResult.errors?.join(", ")}`
441+
`Post-generation pipeline failed: ${pipelineResult.errors?.join(", ")}`,
442+
undefined,
443+
{ code: CliError.Code.InternalError }
428444
);
429445
}
430446
}
@@ -433,7 +449,7 @@ export async function runLocalGenerationForWorkspace({
433449
);
434450

435451
if (results.some((didSucceed) => !didSucceed)) {
436-
context.failAndThrow();
452+
context.failAndThrow(undefined, undefined, { code: CliError.Code.InternalError });
437453
}
438454
}
439455

0 commit comments

Comments
 (0)