From 4b75464b93b5d2d43716cfd0e0fdc3c714037216 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Wed, 25 Feb 2026 17:16:12 -0800 Subject: [PATCH] fix: handle non-JSON error responses in design pipeline Frontend was crashing with "Unexpected token 'I'" when the backend returned plain text errors (e.g. "Internal Server Error" from proxy). Now safely falls back to response.text() when JSON parsing fails. Also prevents backend from swallowing HTTPException in catch-all. Co-Authored-By: Claude Opus 4.6 --- backend/app/api/design_generator.py | 2 ++ frontend/app/design/page.tsx | 33 +++++++++++++++++++++++------ frontend/app/upload/page.tsx | 33 +++++++++++++++++++++++------ 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/backend/app/api/design_generator.py b/backend/app/api/design_generator.py index e8304e4..698d4fa 100644 --- a/backend/app/api/design_generator.py +++ b/backend/app/api/design_generator.py @@ -126,6 +126,8 @@ Square format, clean edges for die-cut sticker.""" status_code=504, detail="AI generation timed out" ) + except HTTPException: + raise except Exception as e: raise HTTPException( status_code=502, diff --git a/frontend/app/design/page.tsx b/frontend/app/design/page.tsx index b74d420..8ada5d0 100644 --- a/frontend/app/design/page.tsx +++ b/frontend/app/design/page.tsx @@ -54,8 +54,15 @@ export default function DesignPage() { }); if (!response.ok) { - const data = await response.json(); - throw new Error(data.detail || "Failed to generate design"); + let message = "Failed to generate design"; + try { + const data = await response.json(); + message = data.detail || message; + } catch { + const text = await response.text(); + message = text || `Server error (${response.status})`; + } + throw new Error(message); } const design = await response.json(); @@ -82,8 +89,15 @@ export default function DesignPage() { ); if (!response.ok) { - const data = await response.json(); - throw new Error(data.detail || "Failed to activate design"); + let message = "Failed to activate design"; + try { + const data = await response.json(); + message = data.detail || message; + } catch { + const text = await response.text(); + message = text || `Server error (${response.status})`; + } + throw new Error(message); } setGeneratedDesign({ ...generatedDesign, status: "active" }); @@ -106,8 +120,15 @@ export default function DesignPage() { ); if (!response.ok) { - const data = await response.json(); - throw new Error(data.detail || "Failed to delete design"); + let message = "Failed to delete design"; + try { + const data = await response.json(); + message = data.detail || message; + } catch { + const text = await response.text(); + message = text || `Server error (${response.status})`; + } + throw new Error(message); } setGeneratedDesign(null); diff --git a/frontend/app/upload/page.tsx b/frontend/app/upload/page.tsx index 952fd2e..22314d3 100644 --- a/frontend/app/upload/page.tsx +++ b/frontend/app/upload/page.tsx @@ -103,8 +103,15 @@ export default function UploadPage() { }); if (!response.ok) { - const data = await response.json(); - throw new Error(data.detail || "Upload failed"); + let message = "Upload failed"; + try { + const data = await response.json(); + message = data.detail || message; + } catch { + const text = await response.text(); + message = text || `Server error (${response.status})`; + } + throw new Error(message); } const design = await response.json(); @@ -127,8 +134,15 @@ export default function UploadPage() { { method: "POST" } ); if (!response.ok) { - const data = await response.json(); - throw new Error(data.detail || "Failed to activate design"); + let message = "Failed to activate design"; + try { + const data = await response.json(); + message = data.detail || message; + } catch { + const text = await response.text(); + message = text || `Server error (${response.status})`; + } + throw new Error(message); } setUploadedDesign({ ...uploadedDesign, status: "active" }); } catch (err) { @@ -146,8 +160,15 @@ export default function UploadPage() { { method: "DELETE" } ); if (!response.ok) { - const data = await response.json(); - throw new Error(data.detail || "Failed to delete design"); + let message = "Failed to delete design"; + try { + const data = await response.json(); + message = data.detail || message; + } catch { + const text = await response.text(); + message = text || `Server error (${response.status})`; + } + throw new Error(message); } resetForm(); } catch (err) {