/** * Error handling utilities for type-safe error processing */ /** * Clerk error structure */ interface ClerkError { errors?: Array<{ message: string; code?: string; }>; message?: string; } /** * Type guard to check if error is a Clerk error */ function isClerkError(error: unknown): error is ClerkError { return ( typeof error === "object" && error !== null && ("errors" in error || "message" in error) ); } /** * Extract error message from unknown error type * Handles Clerk errors, standard Error objects, and unknown types * * @param error - The caught error * @param fallback - Fallback message if no message can be extracted * @returns Error message string */ export function getErrorMessage( error: unknown, fallback = "An unknown error occurred", ): string { // Handle Clerk errors with nested error array if (isClerkError(error)) { if (error.errors?.[0]?.message) { return error.errors[0].message; } if (error.message) { return error.message; } } // Handle standard Error objects if (error instanceof Error) { return error.message; } // Handle string errors if (typeof error === "string") { return error; } // Fallback for unknown types return fallback; } /** * Type guard to check if metadata has a gymId */ interface MetadataWithGymId { gymId: string; } function hasGymId(metadata: unknown): metadata is MetadataWithGymId { return ( typeof metadata === "object" && metadata !== null && "gymId" in metadata && typeof (metadata as Record).gymId === "string" ); } /** * Safely extract gymId from Clerk public metadata * * @param user - Clerk user object * @returns gymId string or empty string if not found */ export function getGymIdFromUser(user: { publicMetadata?: unknown }): string { if (hasGymId(user.publicMetadata)) { return user.publicMetadata.gymId; } return ""; }