diff --git a/surfsense_web/components/tool-ui/video-presentation/errors.ts b/surfsense_web/components/tool-ui/video-presentation/errors.ts new file mode 100644 index 000000000..75d769522 --- /dev/null +++ b/surfsense_web/components/tool-ui/video-presentation/errors.ts @@ -0,0 +1,38 @@ +export function getVideoDownloadErrorToast(err: unknown): { title: string; description: string } { + const msg = err instanceof Error ? err.message.toLowerCase() : ""; + + if (msg.includes("webcodecs") || msg.includes("canrendermediaonweb") || msg.includes("not support")) { + return { + title: "Browser Not Supported", + description: "Video rendering requires Chrome, Edge, or Firefox 130+.", + }; + } + + if (msg.includes("memory") || msg.includes("oom") || msg.includes("allocation")) { + return { + title: "Out of Memory", + description: "The presentation is too large to render. Try closing other tabs.", + }; + } + + return { + title: "Download Failed", + description: "Something went wrong while rendering. Please try again.", + }; +} + +export function getPptxExportErrorToast(err: unknown): { title: string; description: string } { + const msg = err instanceof Error ? err.message.toLowerCase() : ""; + + if (msg.includes("dynamically imported") || msg.includes("failed to fetch") || msg.includes("network")) { + return { + title: "Export Unavailable", + description: "Could not load the export module. Check your network and try again.", + }; + } + + return { + title: "PPTX Export Failed", + description: "Something went wrong while exporting. Please try again.", + }; +} diff --git a/surfsense_web/components/tool-ui/video-presentation/generate-video-presentation.tsx b/surfsense_web/components/tool-ui/video-presentation/generate-video-presentation.tsx index 41ad489c0..061e0200a 100644 --- a/surfsense_web/components/tool-ui/video-presentation/generate-video-presentation.tsx +++ b/surfsense_web/components/tool-ui/video-presentation/generate-video-presentation.tsx @@ -18,6 +18,7 @@ import { buildSlideWithWatermark, type CompiledSlide, } from "./combined-player"; +import { getVideoDownloadErrorToast, getPptxExportErrorToast } from "./errors"; const GenerateVideoPresentationArgsSchema = z.object({ source_content: z.string(), @@ -68,6 +69,7 @@ type GenerateVideoPresentationArgs = z.infer; type VideoPresentationStatusResponse = z.infer; + function parseStatusResponse(data: unknown): VideoPresentationStatusResponse | null { const result = VideoPresentationStatusResponseSchema.safeParse(data); if (!result.success) { @@ -321,9 +323,8 @@ function VideoPresentationPlayer({ URL.revokeObjectURL(url); } catch (err) { if ((err as Error).name !== "AbortError") { - toast.error("Download Failed", { - description: err instanceof Error ? err.message : "Failed to render video", - }); + const { title, description } = getVideoDownloadErrorToast(err); + toast.error(title, { description }); } } finally { setIsRendering(false); @@ -396,9 +397,8 @@ function VideoPresentationPlayer({ for (const r of roots) r.unmount(); document.body.removeChild(offscreen); } catch (err) { - toast.error("PPTX Export Failed", { - description: err instanceof Error ? err.message : "Failed to export PPTX", - }); + const { title, description } = getPptxExportErrorToast(err); + toast.error(title, { description }); } finally { setIsPptxExporting(false); setPptxProgress(null);