Skip to content

Commit c1f3144

Browse files
authored
chore(cli): consolidate small CliError migration branches (#15013)
## Description Consolidates CliError migrations for multiple smaller CLI packages into a single PR: `@fern-api/init`, `@fern-api/project-loader`, `@fern-api/auth`, `@fern-api/api-workspace-validator`, `@fern-api/workspace-loader`, `@fern-api/docs-resolver`, `@fern-api/fern-definition-formatter`, `@fern-api/ir-to-jsonschema`, `@fern-api/login`, `@fern-api/api-workspace-commons`, and others. This is one of the package migration PRs that follow the error classification system introduced in #14749. ## Changes Made Assigned typed error codes across call sites in multiple smaller CLI packages. Also added missing `CliError` imports to all files that reference `CliError.Code`. ### Error codes used | Code | Usage | |------|-------| | `CONFIG_ERROR` | Missing fern directory, invalid project structure, workspace configuration errors | | `AUTH_ERROR` | Organization membership checks, user authentication, login flows | | `NETWORK_ERROR` | API call failures, Auth0 device authorization errors | | `VALIDATION_ERROR` | API workspace validation, docs validation | | `PARSE_ERROR` | OpenAPI/AsyncAPI file loading failures, schema parsing errors | | `REFERENCE_ERROR` | Unresolvable API references in docs | | `VERSION_ERROR` | Version existence checks | ### Files touched (grouped by area) - **Init**: `createFernDirectoryAndOrganization.ts`, `initializeWithMintlify.ts`, `initializeWithReadme.ts` - **Project loader**: `loadProject.ts` - **Auth**: `orgs/createOrganizationIfDoesNotExist.ts`, `users/getCurrentUser.ts` - **Workspace**: `api-workspace-validator/validateAPIWorkspaceAndLogIssues.ts`, `loader/loadAsyncAPIFile.ts`, `loader/loadOpenAPIFile.ts` - **Docs**: `docs-resolver/ApiReferenceNodeConverter.ts` - **Fern definition**: `formatter/formatWorkspace.ts`, `ir-to-jsonschema/JsonSchemaConverterContext.ts` - **Login**: `auth0-login/doAuth0DeviceAuthorizationFlow.ts`, `askToLogin.ts` - **Commons**: `api-workspace-commons/checkVersionExists.ts` ## Testing - [x] Existing tests pass (`pnpm test`, excluding e2e and pre-existing environment failures)
1 parent 70a7da3 commit c1f3144

69 files changed

Lines changed: 479 additions & 184 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/cli/api-importers/asyncapi-to-ir/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"dependencies": {
3434
"@fern-api/ir-sdk": "workspace:*",
3535
"@fern-api/ir-utils": "workspace:*",
36+
"@fern-api/task-context": "workspace:*",
3637
"@fern-api/v3-importer-commons": "workspace:*",
3738
"lodash-es": "catalog:",
3839
"openapi-types": "^12.1.3",

packages/cli/api-importers/asyncapi-to-ir/src/3.0/channel/ChannelConverter3_0.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { HttpHeader, PathParameter, QueryParameter, WebSocketMessage, WebSocketMessageBody } from "@fern-api/ir-sdk";
22
import { constructHttpPath } from "@fern-api/ir-utils";
3+
import { CliError } from "@fern-api/task-context";
34
import { Converters } from "@fern-api/v3-importer-commons";
45
import { OpenAPIV3 } from "openapi-types";
56
import { AbstractChannelConverter } from "../../converters/AbstractChannelConverter.js";
@@ -310,7 +311,10 @@ export class ChannelConverter3_0 extends AbstractChannelConverter<AsyncAPIV3.Cha
310311

311312
private getChannelPathFromOperation(operation: AsyncAPIV3.Operation): string {
312313
if (!operation.channel.$ref.startsWith(CHANNEL_REFERENCE_PREFIX)) {
313-
throw new Error(`Failed to resolve channel path from operation ${operation.channel.$ref}`);
314+
throw new CliError({
315+
message: `Failed to resolve channel path from operation ${operation.channel.$ref}`,
316+
code: CliError.Code.ReferenceError
317+
});
314318
}
315319
return operation.channel.$ref.substring(CHANNEL_REFERENCE_PREFIX.length);
316320
}

packages/cli/api-importers/commons/src/utils/FernDefinitionDirectory.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { RawSchemas } from "@fern-api/fern-definition-schema";
22
import { RelativeFilePath, sep } from "@fern-api/path-utils";
3+
import { CliError } from "@fern-api/task-context";
34

45
export class FernDefinitionDirectory {
56
private files: Record<RelativeFilePath, RawSchemas.DefinitionFileSchema> = {};
@@ -41,7 +42,10 @@ export class FernDefinitionDirectory {
4142
}
4243
const [directory, ...remainingPath] = pathParts;
4344
if (directory == null) {
44-
throw new Error(`Internal error; cannot add file with path: ${pathParts}`);
45+
throw new CliError({
46+
message: `Internal error; cannot add file with path: ${pathParts}`,
47+
code: CliError.Code.InternalError
48+
});
4549
}
4650
if (!this.directories[directory]) {
4751
this.directories[directory] = new FernDefinitionDirectory();

packages/cli/api-importers/conjure/conjure-to-fern/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"@fern-api/fern-definition-schema": "workspace:*",
3838
"@fern-api/fs-utils": "workspace:*",
3939
"@fern-api/importer-commons": "workspace:*",
40+
"@fern-api/task-context": "workspace:*",
4041
"js-yaml": "catalog:"
4142
},
4243
"devDependencies": {

packages/cli/api-importers/conjure/conjure-to-fern/src/ConjureImporter.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { parseEndpointLocator, removeSuffix } from "@fern-api/core-utils";
33
import { RawSchemas } from "@fern-api/fern-definition-schema";
44
import { AbsoluteFilePath, dirname, getFilename, join, RelativeFilePath, relativize } from "@fern-api/fs-utils";
55
import { APIDefinitionImporter, FernDefinitionBuilderImpl, HttpServiceInfo } from "@fern-api/importer-commons";
6+
import { CliError } from "@fern-api/task-context";
67

78
import { listConjureFiles } from "./utils/listConjureFiles.js";
89
import { visitConjureTypeDeclaration } from "./utils/visitConjureTypeDeclaration.js";
@@ -77,7 +78,10 @@ export class ConjureImporter extends APIDefinitionImporter<ConjureImporter.Args>
7778
if (definition.services == null || Object.keys(definition.services ?? {}).length === 0) {
7879
const fernFilePath = this.conjureFilepathToFernFilepath[filepath];
7980
if (fernFilePath == null) {
80-
throw new Error(`Failed to find corresponding fern filepath for conjure file ${filepath}`);
81+
throw new CliError({
82+
message: `Failed to find corresponding fern filepath for conjure file ${filepath}`,
83+
code: CliError.Code.InternalError
84+
});
8185
}
8286

8387
for (const [import_, importedFilepath] of Object.entries(definition.types?.conjureImports ?? {})) {
@@ -151,9 +155,10 @@ export class ConjureImporter extends APIDefinitionImporter<ConjureImporter.Args>
151155
for (const pathParameter of endpointLocator.pathParameters) {
152156
const pathParameterType = endpointDeclaration.args[pathParameter];
153157
if (pathParameterType == null) {
154-
throw new Error(
155-
`Failed to find path parameter ${pathParameter} in ${endpointDeclaration.http}`
156-
);
158+
throw new CliError({
159+
message: `Failed to find path parameter ${pathParameter} in ${endpointDeclaration.http}`,
160+
code: CliError.Code.InternalError
161+
});
157162
}
158163
pathParameters[pathParameter] =
159164
typeof pathParameterType === "string"
@@ -338,9 +343,10 @@ export class ConjureImporter extends APIDefinitionImporter<ConjureImporter.Args>
338343
);
339344
const correspondingFernFilePath = this.conjureFilepathToFernFilepath[relativeFilePathToImportedFile];
340345
if (correspondingFernFilePath == null) {
341-
throw new Error(
342-
`Failed to find corresponding fern filepath for conjure file ${relativeFilePathToImportedFile}`
343-
);
346+
throw new CliError({
347+
message: `Failed to find corresponding fern filepath for conjure file ${relativeFilePathToImportedFile}`,
348+
code: CliError.Code.InternalError
349+
});
344350
}
345351
return correspondingFernFilePath;
346352
}

packages/cli/api-importers/openapi/openapi-ir-to-fern/src/buildEndpoint.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { assertNever, MediaType } from "@fern-api/core-utils";
33
import { RawSchemas } from "@fern-api/fern-definition-schema";
44
import { Endpoint, EndpointExample, Request, RetriesConfiguration, Schema, SchemaId } from "@fern-api/openapi-ir";
55
import { RelativeFilePath } from "@fern-api/path-utils";
6+
import { CliError } from "@fern-api/task-context";
67
import { buildEndpointExample } from "./buildEndpointExample.js";
78
import { ERROR_DECLARATIONS_FILENAME, EXTERNAL_AUDIENCE } from "./buildFernDefinition.js";
89
import { buildHeader } from "./buildHeader.js";
@@ -283,7 +284,10 @@ export function buildEndpoint({
283284
};
284285
},
285286
_other: () => {
286-
throw new Error("Unrecognized Response type: " + endpoint.response?.type);
287+
throw new CliError({
288+
message: "Unrecognized Response type: " + endpoint.response?.type,
289+
code: CliError.Code.InternalError
290+
});
287291
}
288292
});
289293
}

packages/cli/api-importers/openapi/openapi-ir-to-fern/src/buildWebhooks.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
WebhookTimestampFormat
1414
} from "@fern-api/openapi-ir";
1515
import { join, RelativeFilePath } from "@fern-api/path-utils";
16+
import { CliError } from "@fern-api/task-context";
1617
import { camelCase, isEqual } from "lodash-es";
1718
import { buildHeader } from "./buildHeader.js";
1819
import { buildTypeReference } from "./buildTypeReference.js";
@@ -142,7 +143,10 @@ export function buildWebhooks(context: OpenApiIrConverterContext): void {
142143
};
143144
},
144145
_other: () => {
145-
throw new Error("Unrecognized Response type: " + webhook.response?.type);
146+
throw new CliError({
147+
message: "Unrecognized Response type: " + webhook.response?.type,
148+
code: CliError.Code.InternalError
149+
});
146150
}
147151
});
148152
}
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { RawSchemas } from "@fern-api/fern-definition-schema";
22
import { HttpMethod } from "@fern-api/openapi-ir";
3+
import { CliError } from "@fern-api/task-context";
34

45
export function convertToHttpMethod(httpMethod: HttpMethod): RawSchemas.HttpMethodSchema {
56
return HttpMethod._visit<RawSchemas.HttpMethodSchema>(httpMethod, {
@@ -10,13 +11,13 @@ export function convertToHttpMethod(httpMethod: HttpMethod): RawSchemas.HttpMeth
1011
delete: () => RawSchemas.HttpMethodSchema.Delete,
1112
head: () => RawSchemas.HttpMethodSchema.Head,
1213
options: () => {
13-
throw new Error("OPTIONS is unsupported");
14+
throw new CliError({ message: "OPTIONS is unsupported", code: CliError.Code.ConfigError });
1415
},
1516
trace: () => {
16-
throw new Error("TRACE is unsupported");
17+
throw new CliError({ message: "TRACE is unsupported", code: CliError.Code.ConfigError });
1718
},
1819
_other: () => {
19-
throw new Error("Unknown http method is unsupported");
20+
throw new CliError({ message: "Unknown http method is unsupported", code: CliError.Code.ConfigError });
2021
}
2122
});
2223
}

packages/cli/api-importers/openapi/openapi-ir-to-fern/src/utils/getEndpointLocation.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { FERN_PACKAGE_MARKER_FILENAME } from "@fern-api/configuration";
22
import { Endpoint, HttpMethod } from "@fern-api/openapi-ir";
33
import { join, RelativeFilePath } from "@fern-api/path-utils";
4+
import { CliError } from "@fern-api/task-context";
45
import { camelCase, compact, isEqual } from "lodash-es";
5-
66
import { convertEndpointSdkNameToFileWithoutExtension } from "./convertSdkGroupName.js";
77

88
export interface EndpointLocation {
@@ -108,7 +108,10 @@ function getUnresolvedEndpointLocation(endpoint: Endpoint): EndpointLocation {
108108
}
109109

110110
if (fileParts.length >= operationIdTokens.length) {
111-
throw new Error(`Cannot get file for endpoint ${JSON.stringify(endpoint)}`);
111+
throw new CliError({
112+
message: `Cannot get file for endpoint ${JSON.stringify(endpoint)}`,
113+
code: CliError.Code.InternalError
114+
});
112115
}
113116

114117
return {

packages/cli/api-importers/v3-importer-commons/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"@fern-api/ir-sdk": "workspace:*",
4141
"@fern-api/ir-utils": "workspace:*",
4242
"@fern-api/logger": "workspace:*",
43+
"@fern-api/task-context": "workspace:*",
4344
"js-yaml": "catalog:",
4445
"js-yaml-source-map": "catalog:",
4546
"lodash-es": "catalog:",

0 commit comments

Comments
 (0)