Fix SSE crash + React layout error boundaries

- documents_loader: skip missing files (print warning + continue) instead
  of raising HTTPException inside SSE generator — prevents "response
  already started" runtime error when temp files are wiped on restart
- V1ContentRender: wrap non-edit mode render in SlideErrorBoundary so
  broken custom layout components show a red placeholder instead of
  crashing the page (React error #62)
- CustomTemplateCard: wrap LayoutPreview in SlideErrorBoundary for the
  same reason — bad compiled TSX from master deck parsing no longer
  crashes the outline template picker

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vadym Samoilenko 2026-03-01 19:35:27 +00:00
parent 5def8f9e84
commit af95e73806
3 changed files with 13 additions and 10 deletions

View file

@ -1,5 +1,4 @@
import mimetypes
from fastapi import HTTPException
import os, asyncio
from typing import List, Optional, Tuple
import pdfplumber
@ -44,9 +43,8 @@ class DocumentsLoader:
for file_path in self._file_paths:
if not os.path.exists(file_path):
raise HTTPException(
status_code=404, detail=f"File {file_path} not found"
)
print(f"[DocumentsLoader] Warning: file not found, skipping: {file_path}")
continue
document = ""
imgs = []

View file

@ -129,11 +129,13 @@ export const V1ContentRender = ({ slide, isEditMode, theme }: { slide: any, isEd
);
}
return (
<LayoutComp data={{
...slide.content,
_logo_url__: theme ? theme.logo_url : null,
__companyName__: (theme && theme.company_name) ? theme.company_name : null,
}} />
<SlideErrorBoundary label={`Slide ${slide.index + 1}`}>
<LayoutComp data={{
...slide.content,
_logo_url__: theme ? theme.logo_url : null,
__companyName__: (theme && theme.company_name) ? theme.company_name : null,
}} />
</SlideErrorBoundary>
)
};

View file

@ -4,6 +4,7 @@ import { Card } from "@/components/ui/card";
import { CustomTemplates, useCustomTemplatePreview } from "@/app/hooks/useCustomTemplates";
import { Loader2 } from "lucide-react";
import { CompiledLayout } from "@/app/hooks/compileLayout";
import { SlideErrorBoundary } from "../../components/SlideErrorBoundary";
// Memoized preview component to prevent re-renders during scroll
export const LayoutPreview = memo(({ layout, templateId, index }: { layout: CompiledLayout, templateId: string, index: number }) => {
@ -19,7 +20,9 @@ export const LayoutPreview = memo(({ layout, templateId, index }: { layout: Comp
className="transform scale-[0.2] flex justify-center items-center origin-top-left w-[500%] h-[500%]"
style={{ transform: 'scale(0.2) translateZ(0)', backfaceVisibility: 'hidden' }}
>
<LayoutComponent data={layout.sampleData} />
<SlideErrorBoundary label={layout.layoutName}>
<LayoutComponent data={layout.sampleData} />
</SlideErrorBoundary>
</div>
</div>
);