This commit is contained in:
Riccardo Giorato
2026-01-29 22:14:56 +01:00
parent 88cf7f38e2
commit 9b44381deb
2 changed files with 41 additions and 18 deletions
+36 -17
View File
@@ -15,7 +15,10 @@ import {
import { freeTierRateLimit } from "@/lib/rate-limit"; import { freeTierRateLimit } from "@/lib/rate-limit";
import { uploadImageToS3 } from "@/lib/s3-upload"; import { uploadImageToS3 } from "@/lib/s3-upload";
import { buildComicPrompt } from "@/lib/prompt"; import { buildComicPrompt } from "@/lib/prompt";
import { isContentPolicyViolation, getContentPolicyErrorMessage } from "@/lib/utils"; import {
isContentPolicyViolation,
getContentPolicyErrorMessage,
} from "@/lib/utils";
const NEW_MODEL = false; const NEW_MODEL = false;
@@ -34,7 +37,7 @@ export async function POST(request: NextRequest) {
if (!userId) { if (!userId) {
return NextResponse.json( return NextResponse.json(
{ error: "Authentication required" }, { error: "Authentication required" },
{ status: 401 } { status: 401 },
); );
} }
@@ -48,7 +51,7 @@ export async function POST(request: NextRequest) {
if (!storyId || !prompt) { if (!storyId || !prompt) {
return NextResponse.json( return NextResponse.json(
{ error: "Missing required fields: storyId and prompt" }, { error: "Missing required fields: storyId and prompt" },
{ status: 400 } { status: 400 },
); );
} }
@@ -65,8 +68,6 @@ export async function POST(request: NextRequest) {
return NextResponse.json({ error: "Unauthorized" }, { status: 403 }); return NextResponse.json({ error: "Unauthorized" }, { status: 403 });
} }
let page; let page;
let pageNumber; let pageNumber;
let isRedraw = false; let isRedraw = false;
@@ -108,7 +109,7 @@ export async function POST(request: NextRequest) {
const storyData = await getStoryWithPagesBySlug(storyId); const storyData = await getStoryWithPagesBySlug(storyId);
if (storyData) { if (storyData) {
const previousPage = storyData.pages.find( const previousPage = storyData.pages.find(
(p) => p.pageNumber === pageNumber - 1 (p) => p.pageNumber === pageNumber - 1,
); );
if (previousPage?.generatedImageUrl) { if (previousPage?.generatedImageUrl) {
referenceImages.push(previousPage.generatedImageUrl); referenceImages.push(previousPage.generatedImageUrl);
@@ -145,7 +146,11 @@ export async function POST(request: NextRequest) {
let response; let response;
try { try {
console.log("Starting image generation..."); console.log("Starting image generation for ...");
console.dir({
fullPrompt,
referenceImages,
});
const startTime = Date.now(); const startTime = Date.now();
response = await client.images.generate({ response = await client.images.generate({
model: IMAGE_MODEL, model: IMAGE_MODEL,
@@ -164,7 +169,11 @@ export async function POST(request: NextRequest) {
// Clean up DB records if generation failed due to content policy // Clean up DB records if generation failed due to content policy
try { try {
if (error instanceof Error && error.message && error.message.includes("NO_IMAGE")) { if (
error instanceof Error &&
error.message &&
error.message.includes("NO_IMAGE")
) {
if (isRedraw) { if (isRedraw) {
// For redraw, we don't delete the page, just don't update it // For redraw, we don't delete the page, just don't update it
} else { } else {
@@ -173,16 +182,23 @@ export async function POST(request: NextRequest) {
} }
} }
} catch (cleanupError) { } catch (cleanupError) {
console.error("Error cleaning up DB on image generation failure:", cleanupError); console.error(
"Error cleaning up DB on image generation failure:",
cleanupError,
);
} }
if (error instanceof Error && error.message && isContentPolicyViolation(error.message)) { if (
error instanceof Error &&
error.message &&
isContentPolicyViolation(error.message)
) {
return NextResponse.json( return NextResponse.json(
{ {
error: getContentPolicyErrorMessage(), error: getContentPolicyErrorMessage(),
errorType: "content_policy", errorType: "content_policy",
}, },
{ status: 400 } { status: 400 },
); );
} }
@@ -194,7 +210,7 @@ export async function POST(request: NextRequest) {
error: "Insufficient API credits.", error: "Insufficient API credits.",
errorType: "credit_limit", errorType: "credit_limit",
}, },
{ status: 402 } { status: 402 },
); );
} }
return NextResponse.json( return NextResponse.json(
@@ -202,7 +218,7 @@ export async function POST(request: NextRequest) {
error: error.message || `Failed to generate image: ${status}`, error: error.message || `Failed to generate image: ${status}`,
errorType: "api_error", errorType: "api_error",
}, },
{ status: status || 500 } { status: status || 500 },
); );
} }
@@ -212,14 +228,14 @@ export async function POST(request: NextRequest) {
error instanceof Error ? error.message : "Unknown error" error instanceof Error ? error.message : "Unknown error"
}`, }`,
}, },
{ status: 500 } { status: 500 },
); );
} }
if (!response.data || !response.data[0] || !response.data[0].url) { if (!response.data || !response.data[0] || !response.data[0].url) {
return NextResponse.json( return NextResponse.json(
{ error: "No image URL in response" }, { error: "No image URL in response" },
{ status: 500 } { status: 500 },
); );
} }
@@ -235,7 +251,10 @@ export async function POST(request: NextRequest) {
try { try {
await freeTierRateLimit.limit(userId); await freeTierRateLimit.limit(userId);
} catch (rateLimitError) { } catch (rateLimitError) {
console.error("Error applying rate limit after successful generation:", rateLimitError); console.error(
"Error applying rate limit after successful generation:",
rateLimitError,
);
// Don't fail the request if rate limiting fails, just log it // Don't fail the request if rate limiting fails, just log it
} }
} }
@@ -253,7 +272,7 @@ export async function POST(request: NextRequest) {
error instanceof Error ? error.message : "Unknown error" error instanceof Error ? error.message : "Unknown error"
}`, }`,
}, },
{ status: 500 } { status: 500 },
); );
} }
} }
+5 -1
View File
@@ -227,7 +227,11 @@ Only return the JSON, no other text.`;
let response; let response;
try { try {
console.log("Starting image generation..."); console.log("Starting image generation for ...");
console.dir({
fullPrompt,
referenceImages,
});
const startTime = Date.now(); const startTime = Date.now();
response = await client.images.generate({ response = await client.images.generate({
model: IMAGE_MODEL, model: IMAGE_MODEL,