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 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-02-25 17:16:12 -08:00
parent f6b640e4a3
commit 4b75464b93
3 changed files with 56 additions and 12 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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) {