From 9d04ffb63a585743e1da2a581962378669c0c98f Mon Sep 17 00:00:00 2001 From: ajaysi Date: Tue, 31 Mar 2026 07:52:42 +0530 Subject: [PATCH] fix: Add error handling and display for podcast workflow failures - Improve error message handling for common API failures - Add announcementSeverity state for error/success styling - Display errors with red alert styling in podcast dashboard --- .../PodcastMaker/PodcastDashboard.tsx | 8 +++--- .../PodcastDashboard/usePodcastWorkflow.ts | 11 ++++++-- .../PodcastMaker/PodcastDashboard/utils.ts | 26 +++++++++++++++++-- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/PodcastMaker/PodcastDashboard.tsx b/frontend/src/components/PodcastMaker/PodcastDashboard.tsx index 6fb9bafa..f67a0672 100644 --- a/frontend/src/components/PodcastMaker/PodcastDashboard.tsx +++ b/frontend/src/components/PodcastMaker/PodcastDashboard.tsx @@ -177,12 +177,12 @@ const PodcastDashboard: React.FC = () => { {/* Announcements */} {workflow.announcement && ( workflow.setAnnouncement("")} sx={{ - background: "#dbeafe", - border: "1px solid #bfdbfe", - "& .MuiAlert-icon": { color: "#3b82f6" }, + background: workflow.announcementSeverity === "error" ? "#fef2f2" : workflow.announcementSeverity === "success" ? "#f0fdf4" : "#dbeafe", + border: `1px solid ${workflow.announcementSeverity === "error" ? "#fecaca" : workflow.announcementSeverity === "success" ? "#bbf7d0" : "#bfdbfe"}`, + "& .MuiAlert-icon": { color: workflow.announcementSeverity === "error" ? "#ef4444" : workflow.announcementSeverity === "success" ? "#22c55e" : "#3b82f6" }, }} > {workflow.announcement} diff --git a/frontend/src/components/PodcastMaker/PodcastDashboard/usePodcastWorkflow.ts b/frontend/src/components/PodcastMaker/PodcastDashboard/usePodcastWorkflow.ts index 13cf4012..ea1104f2 100644 --- a/frontend/src/components/PodcastMaker/PodcastDashboard/usePodcastWorkflow.ts +++ b/frontend/src/components/PodcastMaker/PodcastDashboard/usePodcastWorkflow.ts @@ -48,6 +48,7 @@ export const usePodcastWorkflow = ({ projectState, onError }: UsePodcastWorkflow const [isAnalyzing, setIsAnalyzing] = useState(false); const [isResearching, setIsResearching] = useState(false); const [announcement, setAnnouncement] = useState(""); + const [announcementSeverity, setAnnouncementSeverity] = useState<"info" | "error" | "success">("info"); const [showResumeAlert, setShowResumeAlert] = useState(false); const [showPreflightDialog, setShowPreflightDialog] = useState(false); const [preflightResponse, setPreflightResponse] = useState(null); @@ -216,10 +217,10 @@ export const usePodcastWorkflow = ({ projectState, onError }: UsePodcastWorkflow setAnnouncement("Subscription limit reached. Please upgrade to continue."); } else { const message = typeof errorDetail === 'string' ? errorDetail : errorDetail.message || errorDetail.error || 'Request limit exceeded'; - announceError(setAnnouncement, new Error(message)); + announceError(setAnnouncement, setAnnouncementSeverityFn, new Error(message)); } } else { - announceError(setAnnouncement, error); + announceError(setAnnouncement, setAnnouncementSeverityFn, error); } } finally { setIsAnalyzing(false); @@ -396,11 +397,16 @@ export const usePodcastWorkflow = ({ projectState, onError }: UsePodcastWorkflow await handleCreate(payload, feedback); }, [project, projectState.knobs, projectState.budgetCap, handleCreate]); + const setAnnouncementSeverityFn = useCallback((severity: "info" | "error" | "success") => { + setAnnouncementSeverity(severity); + }, []); + return { // State isAnalyzing, isResearching, announcement, + announcementSeverity, showResumeAlert, showPreflightDialog, preflightResponse, @@ -415,6 +421,7 @@ export const usePodcastWorkflow = ({ projectState, onError }: UsePodcastWorkflow handleProceedToRendering, toggleQuery, setAnnouncement, + setAnnouncementSeverity: setAnnouncementSeverityFn, setShowResumeAlert, setShowPreflightDialog, setPreflightResponse, diff --git a/frontend/src/components/PodcastMaker/PodcastDashboard/utils.ts b/frontend/src/components/PodcastMaker/PodcastDashboard/utils.ts index da7bb567..5cfa358a 100644 --- a/frontend/src/components/PodcastMaker/PodcastDashboard/utils.ts +++ b/frontend/src/components/PodcastMaker/PodcastDashboard/utils.ts @@ -54,9 +54,31 @@ export const sanitizeExaConfig = ( }; }; -export const announceError = (setAnnouncement: (msg: string) => void, error: unknown) => { - const message = error instanceof Error ? error.message : "Unexpected error"; +export const announceError = ( + setAnnouncement: (msg: string) => void, + setAnnouncementSeverity?: (severity: "info" | "error" | "success") => void, + error?: unknown +) => { + let message = "Unexpected error occurred. Please try again."; + if (error instanceof Error) { + message = error.message; + // Simplify common error messages + if (message.includes("RESOURCE_EXHAUSTED") || message.includes("quota")) { + message = "API quota exceeded. Please check your API keys or try again later."; + } else if (message.includes("All LLM providers failed")) { + message = "AI service temporarily unavailable. Please try again later."; + } else if (message.includes("No LLM API keys configured")) { + message = "API keys not configured. Please contact support."; + } else if (message.includes("RESOURCE_EXHAUSTED")) { + message = "API quota exceeded. Please check your subscription or try again later."; + } else if (message.length > 100) { + message = "An error occurred during analysis. Please try again."; + } + } setAnnouncement(message); + if (setAnnouncementSeverity) { + setAnnouncementSeverity("error"); + } }; export const getStepLabel = (step: string | null): string => {