Skip to content

Commit 7ea8b71

Browse files
author
naman-contentstack
committed
updated the error handling
1 parent c6504e9 commit 7ea8b71

3 files changed

Lines changed: 97 additions & 29 deletions

File tree

src/generateTS/factory.ts

Lines changed: 85 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ export default function (userOptions: TSGenOptions) {
9393
const skippedBlocks: Array<{ uid: string; path: string; reason: string }> =
9494
[];
9595

96+
// Collect numeric identifier errors instead of throwing immediately
97+
const numericIdentifierErrors: Array<{
98+
uid: string;
99+
referenceTo?: string;
100+
type: "content_type" | "global_field";
101+
}> = [];
102+
96103
const typeMap: TypeMap = {
97104
text: { func: type_text, track: true, flag: TypeFlags.BuiltinJS },
98105
number: { func: type_number, track: true, flag: TypeFlags.BuiltinJS },
@@ -153,13 +160,8 @@ export default function (userOptions: TSGenOptions) {
153160
function name_type(uid: string) {
154161
// Check if the UID starts with a number, which would create invalid TypeScript
155162
if (isNumericIdentifier(uid)) {
156-
throwUIDValidationError({
157-
uid,
158-
errorCode: "INVALID_INTERFACE_NAME",
159-
reason: NUMERIC_IDENTIFIER_EXCLUSION_REASON,
160-
suggestion: `Since UIDs cannot be changed, use the --prefix flag to add a valid prefix to all interface names (e.g., --prefix "ContentType")`,
161-
context: "generateTSFromContentTypes",
162-
});
163+
// Return a fallback name to continue processing
164+
return `InvalidInterface_${uid}`;
163165
}
164166

165167
return [options?.naming?.prefix, _.upperFirst(_.camelCase(uid))]
@@ -175,22 +177,35 @@ export default function (userOptions: TSGenOptions) {
175177
let interfaceName: string;
176178

177179
const isGlobalField = contentType.data_type === "global_field";
178-
const identifier = isGlobalField
179-
? (contentType.reference_to as string)
180-
: contentType.uid;
181-
if (isNumericIdentifier(identifier)) {
182-
throwUIDValidationError({
180+
181+
// Check if the content type's own UID starts with a number
182+
if (isNumericIdentifier(contentType.uid)) {
183+
numericIdentifierErrors.push({
183184
uid: contentType.uid,
184-
errorCode: isGlobalField
185-
? "INVALID_GLOBAL_FIELD_REFERENCE"
186-
: "INVALID_CONTENT_TYPE_UID",
187-
reason: NUMERIC_IDENTIFIER_EXCLUSION_REASON,
188-
suggestion: `Since UIDs cannot be changed, use the --prefix flag to add a valid prefix to all interface names (e.g., --prefix "ContentType")`,
189-
context: "generateTSFromContentTypes",
190-
...(isGlobalField && { referenceTo: identifier }),
185+
type: "content_type",
191186
});
187+
// Return a fallback interface declaration to continue processing
188+
interfaceName = `InvalidInterface_${contentType.uid}`;
189+
} else if (
190+
isGlobalField &&
191+
contentType.reference_to &&
192+
isNumericIdentifier(contentType.reference_to as string)
193+
) {
194+
// For global fields, check if the referenced content type has a numeric identifier
195+
// This is a global field error because it references an invalid content type
196+
numericIdentifierErrors.push({
197+
uid: contentType.uid, // The global field's UID
198+
type: "global_field",
199+
referenceTo: contentType.reference_to as string, // The referenced content type's UID
200+
});
201+
// Return a fallback interface declaration to continue processing
202+
interfaceName = `InvalidInterface_${contentType.reference_to}`;
203+
} else {
204+
// No numeric identifier issues, generate normal interface name
205+
interfaceName = name_type(
206+
isGlobalField ? (contentType.reference_to as string) : contentType.uid
207+
);
192208
}
193-
interfaceName = name_type(identifier);
194209

195210
const interface_declaration = ["export interface", interfaceName];
196211
if (systemFields && contentType.schema_type !== "global_field") {
@@ -585,6 +600,56 @@ export default function (userOptions: TSGenOptions) {
585600

586601
const definition = visit_content_type(contentType);
587602

603+
// Check for numeric identifier errors and throw them immediately
604+
if (numericIdentifierErrors.length > 0) {
605+
// Group errors by type for better organization
606+
const contentTypeErrors = numericIdentifierErrors.filter(
607+
(err) => err.type === "content_type"
608+
);
609+
const globalFieldErrors = numericIdentifierErrors.filter(
610+
(err) => err.type === "global_field"
611+
);
612+
613+
// Build the detailed error message
614+
let errorDetails = "";
615+
errorDetails += `Type generation failed: Found ${numericIdentifierErrors.length} items with numeric identifiers that create invalid TypeScript interface names. Please use the --prefix flag to resolve this issue.\n\n`;
616+
617+
if (contentTypeErrors.length > 0) {
618+
errorDetails += "Content Types & Global Fields with Numeric UIDs:\n";
619+
errorDetails +=
620+
"Note: Global Fields are Content Types, so they appear in this section if their own UID starts with a number.\n\n";
621+
622+
contentTypeErrors.forEach((error, index) => {
623+
errorDetails += `${index + 1}. UID: "${error.uid}"\n`;
624+
errorDetails += ` Reason: ${NUMERIC_IDENTIFIER_EXCLUSION_REASON}\n`;
625+
errorDetails += ` Suggestion: Since UIDs cannot be changed, use the --prefix flag to add a valid prefix to all interface names (e.g., --prefix "ContentType")\n\n`;
626+
});
627+
}
628+
629+
if (globalFieldErrors.length > 0) {
630+
errorDetails += "Global Fields Referencing Invalid Content Types:\n\n";
631+
632+
globalFieldErrors.forEach((error, index) => {
633+
errorDetails += `${index + 1}. Global Field: "${error.uid}"\n`;
634+
errorDetails += ` References: "${error.referenceTo || "Unknown"}"\n`;
635+
errorDetails += ` Reason: ${NUMERIC_IDENTIFIER_EXCLUSION_REASON}\n`;
636+
errorDetails += ` Suggestion: Since UIDs cannot be changed, use the --prefix flag to add a valid prefix to all interface names (e.g., --prefix "ContentType")\n\n`;
637+
});
638+
}
639+
640+
errorDetails += "To resolve these issues:\n";
641+
errorDetails +=
642+
" • Use the --prefix flag to add a valid prefix to all interface names\n";
643+
errorDetails += " • Example: --prefix 'ContentType'\n";
644+
645+
// Throw a comprehensive error with all the details
646+
throw {
647+
type: "validation",
648+
error_code: "VALIDATION_ERROR",
649+
error_message: errorDetails,
650+
};
651+
}
652+
588653
// Log summary table of skipped fields and blocks
589654
if (skippedFields.length > 0 || skippedBlocks.length > 0) {
590655
cliux.print("");

src/generateTS/index.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,19 @@ export const generateTSFromContentTypes = async ({
182182

183183
return output;
184184
} catch (err: any) {
185-
// Use common function to create detailed error information
186-
const errorDetails = createErrorDetails(err, "generateTSFromContentTypes");
185+
// Handle numeric identifier errors specially to preserve their detailed format
186+
if (
187+
err.type === "validation" &&
188+
err.error_code === "VALIDATION_ERROR" &&
189+
err.error_message &&
190+
err.error_message.includes("numeric identifiers")
191+
) {
192+
// Pass through the detailed error as-is
193+
throw err;
194+
}
187195

188-
// Don't log the error here - let the CLI handle the display
196+
// Use common function to create detailed error information for other errors
197+
const errorDetails = createErrorDetails(err, "generateTSFromContentTypes");
189198
throw errorDetails;
190199
}
191200
};

src/generateTS/shared/utils.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,6 @@ export function createErrorDetails(
132132
return {
133133
error_message: err.error_message || "Validation error occurred", // Keep for backwards compatibility
134134
error_code: err.error_code || "VALIDATION_ERROR", // New property
135-
context,
136-
timestamp: new Date().toISOString(),
137-
error_type: "ValidationError",
138135
details: err.details || {},
139136
};
140137
} else {
@@ -143,9 +140,6 @@ export function createErrorDetails(
143140
return {
144141
error_message: `Type generation failed: ${errorMessage}`, // Keep for backwards compatibility
145142
error_code: "TYPE_GENERATION_FAILED", // New property
146-
context,
147-
timestamp: new Date().toISOString(),
148-
error_type: err.constructor.name,
149143
details: {},
150144
};
151145
}

0 commit comments

Comments
 (0)