Skip to content

Commit 0704cdc

Browse files
committed
chore(cli): migrate @fern-api/ir-generator to use CliError
1 parent f501e76 commit 0704cdc

30 files changed

Lines changed: 314 additions & 118 deletions

packages/cli/generation/ir-generator/src/PackageTreeGenerator.ts

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
WebSocketChannelId
1515
} from "@fern-api/ir-sdk";
1616
import { FilteredIr, getOriginalName, IdGenerator } from "@fern-api/ir-utils";
17+
import { CliError } from "@fern-api/task-context";
1718
import { mapValues } from "lodash-es";
1819

1920
type UnprocessedPackage = Omit<Package, "hasEndpointsInTree">;
@@ -40,7 +41,10 @@ export class PackageTreeGenerator {
4041
public addPackageRedirection({ from, to }: { from: FernFilepath; to: FernFilepath }): void {
4142
const package_ = this.getPackageForFernFilepath(from);
4243
if (package_.navigationConfig != null) {
43-
throw new Error("Found duplicate navigationConfig for package");
44+
throw new CliError({
45+
message: "Found duplicate navigationConfig for package",
46+
code: CliError.Code.InternalError
47+
});
4448
}
4549
package_.navigationConfig = {
4650
pointsTo: IdGenerator.generateSubpackageId(to)
@@ -50,7 +54,7 @@ export class PackageTreeGenerator {
5054
public addDocs(fernFilepath: FernFilepath, docs: string): void {
5155
const package_ = this.getPackageForFernFilepath(fernFilepath);
5256
if (package_.docs != null) {
53-
throw new Error("Found duplicate docs for package");
57+
throw new CliError({ message: "Found duplicate docs for package", code: CliError.Code.InternalError });
5458
}
5559
package_.docs = docs;
5660
}
@@ -70,23 +74,32 @@ export class PackageTreeGenerator {
7074
public addService(serviceId: ServiceId, service: HttpService): void {
7175
const package_ = this.getPackageForFernFilepath(service.name.fernFilepath);
7276
if (package_.service != null) {
73-
throw new Error("Found duplicate service for " + serviceId);
77+
throw new CliError({
78+
message: "Found duplicate service for " + serviceId,
79+
code: CliError.Code.InternalError
80+
});
7481
}
7582
package_.service = serviceId;
7683
}
7784

7885
public addWebhookGroup(webhookGroupId: WebhookGroupId, fernFilepath: FernFilepath): void {
7986
const package_ = this.getPackageForFernFilepath(fernFilepath);
8087
if (package_.webhooks != null) {
81-
throw new Error("Found duplicate webhook group for " + webhookGroupId);
88+
throw new CliError({
89+
message: "Found duplicate webhook group for " + webhookGroupId,
90+
code: CliError.Code.InternalError
91+
});
8292
}
8393
package_.webhooks = webhookGroupId;
8494
}
8595

8696
public addWebSocketChannel(websocketChannelId: WebSocketChannelId, fernFilepath: FernFilepath): void {
8797
const package_ = this.getPackageForFernFilepath(fernFilepath);
8898
if (package_.webhooks != null) {
89-
throw new Error("Found duplicate webhook group for " + websocketChannelId);
99+
throw new CliError({
100+
message: "Found duplicate webhook group for " + websocketChannelId,
101+
code: CliError.Code.InternalError
102+
});
90103
}
91104
package_.websocket = websocketChannelId;
92105
}
@@ -152,26 +165,35 @@ export class PackageTreeGenerator {
152165

153166
public sortRootPackage(subpackagesInOrder: SubpackageId[]): void {
154167
if (!isEqualIgnoreOrder(this.rootPackage.subpackages, subpackagesInOrder)) {
155-
throw new Error("Sorted subpackages differ from unsorted packages in root");
168+
throw new CliError({
169+
message: "Sorted subpackages differ from unsorted packages in root",
170+
code: CliError.Code.InternalError
171+
});
156172
}
157173
this.rootPackage.subpackages = subpackagesInOrder;
158174
}
159175

160176
public sortSubpackage(subpackageId: SubpackageId, subpackagesInOrder: SubpackageId[]): void {
161177
const subpackage = this.subpackages[subpackageId];
162178
if (subpackage == null) {
163-
throw new Error("Subpackage does not exist: " + subpackageId);
179+
throw new CliError({
180+
message: "Subpackage does not exist: " + subpackageId,
181+
code: CliError.Code.ResolutionError
182+
});
164183
}
165184
if (!isEqualIgnoreOrder(subpackage.subpackages, subpackagesInOrder)) {
166-
throw new Error("Sorted subpackages differ from unsorted packages");
185+
throw new CliError({
186+
message: "Sorted subpackages differ from unsorted packages",
187+
code: CliError.Code.InternalError
188+
});
167189
}
168190
subpackage.subpackages = subpackagesInOrder;
169191
}
170192

171193
private getAllSubpackagesWithEndpoints(root: SubpackageId): SubpackageId[] {
172194
const subpackage = this.subpackages[root];
173195
if (subpackage == null) {
174-
throw new Error("Subpackage does not exist: " + root);
196+
throw new CliError({ message: "Subpackage does not exist: " + root, code: CliError.Code.ResolutionError });
175197
}
176198

177199
const subpackagesWithEndpoints = this.getAllChildrenWithEndpoints(subpackage);
@@ -200,7 +222,10 @@ export class PackageTreeGenerator {
200222
const subpackagesInParent = parent.subpackages.map((subpackageId) => {
201223
const subpackage = this.subpackages[subpackageId];
202224
if (subpackage == null) {
203-
throw new Error("Subpackage ID is invalid: " + subpackageId);
225+
throw new CliError({
226+
message: "Subpackage ID is invalid: " + subpackageId,
227+
code: CliError.Code.InternalError
228+
});
204229
}
205230
return subpackage;
206231
});

packages/cli/generation/ir-generator/src/converters/convertApiAuth.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
InferredAuthSchemeTokenEndpoint,
88
OAuthConfiguration
99
} from "@fern-api/ir-sdk";
10+
import { CliError } from "@fern-api/task-context";
1011

1112
import { FernFileContext } from "../FernFileContext.js";
1213
import { EndpointResolver } from "../resolvers/EndpointResolver.js";
@@ -105,7 +106,7 @@ function convertSchemeReference({
105106
const convertNamedAuthSchemeReference = (reference: string, docs: string | undefined) => {
106107
const declaration = authSchemeDeclarations?.[reference];
107108
if (declaration == null) {
108-
throw new Error("Unknown auth scheme: " + reference);
109+
throw new CliError({ message: "Unknown auth scheme: " + reference, code: CliError.Code.ReferenceError });
109110
}
110111
return visitRawAuthSchemeDeclaration<AuthScheme>(declaration, {
111112
header: (rawHeader) =>
@@ -265,7 +266,10 @@ function generateOAuth({
265266
)
266267
});
267268
default:
268-
throw new Error(`Unknown OAuth type: '${rawScheme?.type}'`);
269+
throw new CliError({
270+
message: `Unknown OAuth type: '${rawScheme?.type}'`,
271+
code: CliError.Code.InternalError
272+
});
269273
}
270274
}
271275

packages/cli/generation/ir-generator/src/converters/convertChannel.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
WebSocketMessageBody
1717
} from "@fern-api/ir-sdk";
1818
import { constructHttpPath, getOriginalName } from "@fern-api/ir-utils";
19+
import { CliError } from "@fern-api/task-context";
1920
import { FernFileContext } from "../FernFileContext.js";
2021
import { getHeaderName } from "../index.js";
2122
import { ExampleResolver } from "../resolvers/ExampleResolver.js";
@@ -135,7 +136,10 @@ export function convertChannel({
135136
? Object.entries(example["query-parameters"]).map(([wireKey, value]) => {
136137
const queryParameterDeclaration = channel["query-parameters"]?.[wireKey];
137138
if (queryParameterDeclaration == null) {
138-
throw new Error(`Query parameter ${wireKey} does not exist`);
139+
throw new CliError({
140+
message: `Query parameter ${wireKey} does not exist`,
141+
code: CliError.Code.ReferenceError
142+
});
139143
}
140144
return {
141145
name: file.casingsGenerator.generateNameAndWireValue({
@@ -164,7 +168,10 @@ export function convertChannel({
164168
messages: example.messages.map((messageExample): ExampleWebSocketMessage => {
165169
const message = channel.messages?.[messageExample.type];
166170
if (message == null) {
167-
throw new Error(`Message ${messageExample.type} does not exist`);
171+
throw new CliError({
172+
message: `Message ${messageExample.type} does not exist`,
173+
code: CliError.Code.InternalError
174+
});
168175
}
169176
return {
170177
type: messageExample.type,
@@ -225,7 +232,7 @@ function convertExampleWebSocketMessageBody({
225232
}
226233

227234
if (!isPlainObject(example)) {
228-
throw new Error("Example must be an object");
235+
throw new CliError({ message: "Example must be an object", code: CliError.Code.ValidationError });
229236
}
230237

231238
const exampleProperties: ExampleInlinedRequestBodyProperty[] = [];
@@ -259,7 +266,10 @@ function convertExampleWebSocketMessageBody({
259266
file
260267
});
261268
if (originalTypeDeclaration == null) {
262-
throw new Error("Could not find original type declaration for property: " + wireKey);
269+
throw new CliError({
270+
message: "Could not find original type declaration for property: " + wireKey,
271+
code: CliError.Code.ResolutionError
272+
});
263273
}
264274
exampleProperties.push({
265275
name: file.casingsGenerator.generateNameAndWireValue({
@@ -391,7 +401,10 @@ function convertChannelPathParameters({
391401
})
392402
);
393403
} else {
394-
throw new Error(`Path parameter ${key} does not exist`);
404+
throw new CliError({
405+
message: `Path parameter ${key} does not exist`,
406+
code: CliError.Code.ReferenceError
407+
});
395408
}
396409
}
397410
}

packages/cli/generation/ir-generator/src/converters/convertOAuthClientCredentials.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { RawSchemas } from "@fern-api/fern-definition-schema";
22
import { OAuthClientCredentials } from "@fern-api/ir-sdk";
3-
3+
import { CliError } from "@fern-api/task-context";
44
import { FernFileContext } from "../FernFileContext.js";
55
import { EndpointResolver } from "../resolvers/EndpointResolver.js";
66
import { PropertyResolver } from "../resolvers/PropertyResolver.js";
@@ -34,7 +34,10 @@ export function convertOAuthClientCredentials({
3434
tokenEndpoint
3535
});
3636
if (oauthTokenEndpoint == null) {
37-
throw new Error("Failed to convert OAuth token endpoint.");
37+
throw new CliError({
38+
message: "Failed to convert OAuth token endpoint.",
39+
code: CliError.Code.IrConversionError
40+
});
3841
}
3942
const refreshEndpoint =
4043
refreshTokenEndpoint != null

packages/cli/generation/ir-generator/src/converters/convertReadmeConfig.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { generatorsYml } from "@fern-api/configuration";
22
import { HttpEndpoint, HttpService, ReadmeConfig, ServiceId } from "@fern-api/ir-sdk";
3+
import { CliError } from "@fern-api/task-context";
34
import urlJoin from "url-join";
45

56
export function convertReadmeConfig({
@@ -58,7 +59,10 @@ class ReadmeEndpointCache {
5859
public getEndpointForReadmeOrThrow(readmeEndpoint: generatorsYml.ReadmeEndpointSchema): HttpEndpoint {
5960
const endpoint = this.getEndpointForReadme(readmeEndpoint);
6061
if (endpoint == null) {
61-
throw new Error(`Endpoint not found for ${JSON.stringify(readmeEndpoint)}`);
62+
throw new CliError({
63+
message: `Endpoint not found for ${JSON.stringify(readmeEndpoint)}`,
64+
code: CliError.Code.ResolutionError
65+
});
6266
}
6367
return endpoint;
6468
}
@@ -117,7 +121,7 @@ function getReadmeEndpointObject({
117121
if (typeof endpoint === "string") {
118122
const split = endpoint.split(" ");
119123
if (split.length !== 2 || split[0] == null || split[1] == null) {
120-
throw new Error(`invalid endpoint string: ${endpoint}`);
124+
throw new CliError({ message: `invalid endpoint string: ${endpoint}`, code: CliError.Code.ParseError });
121125
}
122126
return {
123127
method: split[0],

packages/cli/generation/ir-generator/src/converters/convertWebhookGroup.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import {
3232
WebhookTimestampFormat
3333
} from "@fern-api/ir-sdk";
3434
import { IdGenerator, isReferencedWebhookPayloadSchema } from "@fern-api/ir-utils";
35-
35+
import { CliError } from "@fern-api/task-context";
3636
import { FernFileContext } from "../FernFileContext.js";
3737
import { ExampleResolver } from "../resolvers/ExampleResolver.js";
3838
import { TypeResolver } from "../resolvers/TypeResolver.js";
@@ -200,7 +200,10 @@ function convertWebhookExamples({
200200
}));
201201
}
202202
if (!isPlainObject(webhook.payload)) {
203-
throw new Error(`Example webhook payload is not an object. Got: ${JSON.stringify(webhook.payload)}`);
203+
throw new CliError({
204+
message: `Example webhook payload is not an object. Got: ${JSON.stringify(webhook.payload)}`,
205+
code: CliError.Code.ValidationError
206+
});
204207
}
205208
// The payload example is a simple object of key, value pairs, so we format the example as
206209
// a map<string, unknown> for simplicity. If we ever add support for webhooks in the generated

packages/cli/generation/ir-generator/src/converters/services/convertExampleEndpointCall.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import {
2424
NameOrString
2525
} from "@fern-api/ir-sdk";
2626
import { getOriginalName, hashJSON } from "@fern-api/ir-utils";
27+
import { CliError } from "@fern-api/task-context";
2728
import urlJoin from "url-join";
28-
2929
import { FernFileContext } from "../../FernFileContext.js";
3030
import { ErrorResolver } from "../../resolvers/ErrorResolver.js";
3131
import { ExampleResolver } from "../../resolvers/ExampleResolver.js";
@@ -89,7 +89,10 @@ export function convertExampleEndpointCall({
8989
? endpoint.request?.["query-parameters"]?.[wireKey]
9090
: undefined;
9191
if (queryParameterDeclaration == null) {
92-
throw new Error(`Query parameter ${wireKey} does not exist`);
92+
throw new CliError({
93+
message: `Query parameter ${wireKey} does not exist`,
94+
code: CliError.Code.ReferenceError
95+
});
9396
}
9497
const isAllowMultiple =
9598
typeof queryParameterDeclaration !== "string" &&
@@ -252,7 +255,10 @@ function convertPathParameters({
252255
})
253256
);
254257
} else {
255-
throw new Error(`Path parameter ${key} does not exist`);
258+
throw new CliError({
259+
message: `Path parameter ${key} does not exist`,
260+
code: CliError.Code.ReferenceError
261+
});
256262
}
257263
}
258264
}
@@ -405,7 +411,10 @@ function convertExampleRequestBody({
405411
}
406412

407413
if (!isPlainObject(example.request)) {
408-
throw new Error(`Example is not an object. Got: ${JSON.stringify(example.request)}`);
414+
throw new CliError({
415+
message: `Example is not an object. Got: ${JSON.stringify(example.request)}`,
416+
code: CliError.Code.ValidationError
417+
});
409418
}
410419

411420
const exampleProperties: ExampleInlinedRequestBodyProperty[] = [];
@@ -463,7 +472,10 @@ function convertExampleRequestBody({
463472
});
464473
continue;
465474
}
466-
throw new Error("Could not find original type declaration for property: " + wireKey);
475+
throw new CliError({
476+
message: "Could not find original type declaration for property: " + wireKey,
477+
code: CliError.Code.ResolutionError
478+
});
467479
}
468480
exampleProperties.push({
469481
name: file.casingsGenerator.generateNameAndWireValue({

packages/cli/generation/ir-generator/src/converters/services/convertHttpRequestBody.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
HttpRequestBodyReference,
1414
InlinedRequestBodyProperty
1515
} from "@fern-api/ir-sdk";
16-
16+
import { CliError } from "@fern-api/task-context";
1717
import { FernFileContext } from "../../FernFileContext.js";
1818
import { parseTypeName } from "../../utils/parseTypeName.js";
1919
import { convertAvailability } from "../convertDeclaration.js";
@@ -102,7 +102,7 @@ export function convertHttpRequestBody({
102102

103103
if (isInlineRequestBody(request.body)) {
104104
if (request.name == null) {
105-
throw new Error("Name is missing for inlined request");
105+
throw new CliError({ message: "Name is missing for inlined request", code: CliError.Code.InternalError });
106106
}
107107

108108
return HttpRequestBody.inlinedRequestBody({

packages/cli/generation/ir-generator/src/converters/services/convertHttpSdkRequest.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { isInlineRequestBody, parseRawBytesType, RawSchemas } from "@fern-api/fern-definition-schema";
22
import { SdkRequest, SdkRequestBodyType, SdkRequestShape } from "@fern-api/ir-sdk";
3+
import { CliError } from "@fern-api/task-context";
34
import { size } from "lodash-es";
4-
55
import { FernFileContext } from "../../FernFileContext.js";
66
import { PropertyResolver } from "../../resolvers/PropertyResolver.js";
77
import { TypeResolver } from "../../resolvers/TypeResolver.js";
@@ -59,7 +59,7 @@ function convertHttpSdkRequestShape({
5959
}): SdkRequestShape | undefined {
6060
const constructWrapper = () => {
6161
if (typeof request === "string" || request?.name == null) {
62-
throw new Error("Name is missing for request wrapper");
62+
throw new CliError({ message: "Name is missing for request wrapper", code: CliError.Code.InternalError });
6363
}
6464
return SdkRequestShape.wrapper({
6565
wrapperName: file.casingsGenerator.generateName(request.name),

packages/cli/generation/ir-generator/src/converters/services/convertHttpService.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
} from "@fern-api/ir-sdk";
1919
import { constructHttpPath, IdGenerator } from "@fern-api/ir-utils";
2020
import { SourceResolver } from "@fern-api/source-resolver";
21+
import { CliError } from "@fern-api/task-context";
2122
import urlJoin from "url-join";
2223
import { FernFileContext } from "../../FernFileContext.js";
2324
import { ErrorResolver } from "../../resolvers/ErrorResolver.js";
@@ -372,7 +373,7 @@ export function resolvePathParameterOrThrow({
372373
file
373374
});
374375
if (resolved == null) {
375-
throw new Error("Cannot resolve path parameter");
376+
throw new CliError({ message: "Cannot resolve path parameter", code: CliError.Code.InternalError });
376377
}
377378
return resolved;
378379
}

0 commit comments

Comments
 (0)