feat: enhance export functionality and error handling in presentation generation

- Updated the export URL construction to include optional FastAPI URL from query parameters.
- Improved error handling when applying themes during PDF export to prevent blocking rendering.
- Added validation for theme font properties to ensure proper application.
This commit is contained in:
sudipnext 2026-03-26 16:35:15 +05:45
parent 653e35bb3d
commit 47295572fe
3 changed files with 40 additions and 3 deletions

View file

@ -22,7 +22,11 @@ export function setupExportHandlers() {
ipcMain.handle("export-presentation", async (_, id: string, title: string, exportAs: "pptx" | "pdf" | "png") => {
try {
const pptUrl = `${process.env.NEXT_PUBLIC_URL}/pdf-maker?id=${id}`;
const params = new URLSearchParams({ id });
if (process.env.NEXT_PUBLIC_FAST_API) {
params.set("fastapiUrl", process.env.NEXT_PUBLIC_FAST_API);
}
const pptUrl = `${process.env.NEXT_PUBLIC_URL}/pdf-maker?${params.toString()}`;
let exportTask = {
type: "export",

View file

@ -63,7 +63,12 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => {
dispatch(setPresentationData(data));
setContentLoading(false);
if (data?.theme) {
applyTheme(data.theme);
try {
applyTheme(data.theme);
} catch (themeError) {
// Theme issues should not block export rendering.
console.warn("Theme application skipped for pdf-maker:", themeError);
}
}
} catch (error) {
setError(true);
@ -78,6 +83,7 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => {
if (!element) return;
if (!theme || !theme.data) { return; }
if (!theme.data.colors['graph_0']) { return; }
if (!theme.data.fonts?.textFont?.name || !theme.data.fonts?.textFont?.url) { return; }
const cssVariables = {
'--primary-color': theme.data.colors['primary'],
'--background-color': theme.data.colors['background'],

View file

@ -1,5 +1,10 @@
// Utility to get the FastAPI base URL
export function getFastAPIUrl(): string {
const queryFastApiUrl = getFastApiUrlFromQuery();
if (queryFastApiUrl) {
return queryFastApiUrl;
}
// Prefer Electron-preload env when available
if (typeof window !== "undefined" && (window as any).env?.NEXT_PUBLIC_FAST_API) {
return (window as any).env.NEXT_PUBLIC_FAST_API;
@ -14,6 +19,23 @@ export function getFastAPIUrl(): string {
return "http://127.0.0.1:8000";
}
function getFastApiUrlFromQuery(): string | null {
if (typeof window === "undefined") return null;
try {
const params = new URLSearchParams(window.location.search);
const value = params.get("fastapiUrl");
if (!value) return null;
const parsed = new URL(value);
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
return null;
}
return parsed.origin;
} catch {
return null;
}
}
function isAbsoluteHttpUrl(path: string): boolean {
return /^https?:\/\//i.test(path);
}
@ -34,10 +56,15 @@ export function getApiUrl(path: string): string {
const normalizedPath = withLeadingSlash(path);
const isFastApiEndpoint = normalizedPath.startsWith("/api/v1/");
const hasWindowFastApi = typeof window !== "undefined" && !!(window as any).env?.NEXT_PUBLIC_FAST_API;
const hasQueryFastApi = !!getFastApiUrlFromQuery();
// In web/docker, /api/v1 is typically reverse-proxied by the web server.
// In Electron, Next and FastAPI run on different ports, so use FastAPI base URL.
if (isFastApiEndpoint && (isElectronRuntime() || !!process.env.NEXT_PUBLIC_FAST_API)) {
if (
isFastApiEndpoint &&
(isElectronRuntime() || !!process.env.NEXT_PUBLIC_FAST_API || hasWindowFastApi || hasQueryFastApi)
) {
return `${getFastAPIUrl()}${normalizedPath}`;
}