import { useState } from 'react' import { AlertCircle, ChevronDown, ChevronRight, X } from 'lucide-react' import type { GenerationError } from '../lib/generation-errors' interface GenerationErrorDialogProps { error: GenerationError onDismiss: () => void } function assertNever(value: never): never { throw new Error(`Unexpected generation error variant: ${JSON.stringify(value)}`) } function getGenericHumanMessage(message: string): string { const lower = message.toLowerCase() if (lower.includes('409') || lower.includes('already')) { return 'A generation is already in progress. Please wait for it to finish or cancel it.' } if (lower.includes('cuda') || lower.includes('out of memory') || lower.includes('oom')) { return 'The GPU ran out of memory. Try a lower resolution or shorter duration.' } if ((lower.includes('model') && (lower.includes('not found') || lower.includes('load')))) { return 'The AI model failed to load. Please check your setup and try again.' } if (lower.includes('fetch') || lower.includes('network') || lower.includes('econnrefused')) { return 'Could not connect to the generation server. Make sure the backend is running.' } if (lower.includes('input image') || lower.includes('canvas') || lower.includes('cors')) { return 'Failed to prepare the input image. The file may be corrupted or inaccessible.' } if (lower.includes('could not auto-generate') || lower.includes('send to genspace')) { return message } return 'Something went wrong during generation. Please try again.' } function getDialogModel(error: GenerationError): { humanMessage: string technicalDetails: string primaryAction?: { label: string onClick: () => void } } { switch (error.status) { case 402: switch (error.error.code) { case 'LTX_INSUFFICIENT_FUNDS': return { humanMessage: 'Your LTX API credits are insufficient for this generation. Buy more credits in LTX and try again.', technicalDetails: JSON.stringify(error.error, null, 2), primaryAction: { label: 'Buy Credits', onClick: () => { void window.electronAPI.openLtxBillingPage() }, }, } } return assertNever(error.error.code) case '4XX': case '5XX': case 'default': return { humanMessage: getGenericHumanMessage(error.error.message), technicalDetails: JSON.stringify(error.error, null, 2), } default: return assertNever(error) } } export function GenerationErrorDialog({ error, onDismiss }: GenerationErrorDialogProps) { const [detailsExpanded, setDetailsExpanded] = useState(false) const dialogModel = getDialogModel(error) return (
{dialogModel.humanMessage}
{dialogModel.technicalDetails}
)}