Corrige ReferenceError safeExtractError e adiciona retries resilientes multi-engine no gerador de imagens

This commit is contained in:
2026-08-31 14:24:36 +00:00
parent a08c741a4f
commit e994ac1c40
2 changed files with 53 additions and 19 deletions
+20
View File
@@ -11,6 +11,26 @@ function escapeHtml(text) {
.replace(/'/g, "'"); .replace(/'/g, "'");
} }
// Helper global para extração segura de erros de resposta HTTP no frontend
async function safeExtractError(resp, defaultMsg = 'Erro na operação') {
if (!resp) return defaultMsg;
try {
const text = await resp.text();
try {
const json = JSON.parse(text);
return json.error || defaultMsg;
} catch (e) {
if (resp.status === 502 || text.includes('Bad Gateway')) {
return 'O servidor está temporariamente ocupado processando a requisição. Por favor, tente novamente em instantes.';
}
return text.slice(0, 160) || defaultMsg;
}
} catch (e) {
return defaultMsg;
}
}
// Função global para exibir notificações elegantes estilo Toast // Função global para exibir notificações elegantes estilo Toast
function showToast(message, type = 'info') { function showToast(message, type = 'info') {
let container = document.getElementById('toast-container'); let container = document.getElementById('toast-container');
+24 -10
View File
@@ -586,30 +586,44 @@ app.post('/api/comics/generate-frame', requireAuth, async (req, res) => {
console.warn('[Comics Image] Falha/Timeout no MiniMax image-01 (' + minimaxErr.message + '), acionando gerador fallback...'); console.warn('[Comics Image] Falha/Timeout no MiniMax image-01 (' + minimaxErr.message + '), acionando gerador fallback...');
} }
// Tentativa 2 (Fallback): Pollinations FLUX de alta resolução estilizado 3D Pixar // Tentativa 2 (Fallback Resiliente Multi-Engine com Retries):
if (!imageBuffer) { if (!imageBuffer) {
providerUsed = 'pollinations-flux'; const is169 = proporcao === '16:9' || (prompt && prompt.includes('16:9'));
try {
const is169 = proporcao === '16:9' || prompt.includes('16:9');
const width = is169 ? 1280 : 1024; const width = is169 ? 1280 : 1024;
const height = is169 ? 720 : 768; const height = is169 ? 720 : 768;
const enhancedPrompt = encodeURIComponent(`${prompt}, 3d pixar disney style, digital children book illustration, vibrant colors, masterpiece, cinematic lighting`); const cleanPrompt = (prompt || 'cute children book illustration').replace(/[^\w\s,.-]/gi, '');
const fallbackUrl = `https://image.pollinations.ai/prompt/${enhancedPrompt}?width=${width}&height=${height}&nologo=true&seed=${Math.floor(Math.random() * 100000)}`; const enhancedPrompt = encodeURIComponent(`${cleanPrompt}, 3d pixar disney style, digital children book illustration, vibrant colors, masterpiece, cinematic lighting`);
const engines = ['flux', 'turbo'];
for (const engine of engines) {
if (imageBuffer) break;
for (let attempt = 1; attempt <= 2; attempt++) {
try {
providerUsed = `pollinations-${engine}`;
const seed = Math.floor(Math.random() * 1000000);
const fallbackUrl = `https://image.pollinations.ai/prompt/${enhancedPrompt}?width=${width}&height=${height}&model=${engine}&nologo=true&seed=${seed}`;
const controller = new AbortController(); const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000); const timeoutId = setTimeout(() => controller.abort(), 25000);
const fbResp = await fetch(fallbackUrl, { signal: controller.signal }); const fbResp = await fetch(fallbackUrl, { signal: controller.signal });
clearTimeout(timeoutId); clearTimeout(timeoutId);
if (fbResp.ok) { if (fbResp.ok) {
imageBuffer = Buffer.from(await fbResp.arrayBuffer()); imageBuffer = Buffer.from(await fbResp.arrayBuffer());
console.log('[Comics Image] Imagem gerada com sucesso via Fallback Inteligente (Pollinations Flux).'); console.log(`[Comics Image] Imagem gerada com sucesso via Fallback (${providerUsed}, tentativa ${attempt}).`);
break;
} else { } else {
throw new Error(`Fallback HTTP ${fbResp.status}`); console.warn(`[Comics Image] Fallback ${providerUsed} tentativa ${attempt} respondeu ${fbResp.status}`);
if (fbResp.status === 429) {
await new Promise(r => setTimeout(r, 700 * attempt));
}
} }
} catch (fbErr) { } catch (fbErr) {
console.error('[Comics Image] Erro também no provedor Fallback:', fbErr.message); console.warn(`[Comics Image] Erro no fallback ${engine} tentativa ${attempt}:`, fbErr.message);
}
}
} }
} }