From 19bb7fffbc9796b98a7f5c1001d0520ebe0ebaea Mon Sep 17 00:00:00 2001 From: pollutri Date: Thu, 11 Jun 2026 18:24:18 +0200 Subject: [PATCH] Diagnostica step-by-step upload PDF in console --- app/admin/page.tsx | 106 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 85 insertions(+), 21 deletions(-) diff --git a/app/admin/page.tsx b/app/admin/page.tsx index f383097..c535632 100644 --- a/app/admin/page.tsx +++ b/app/admin/page.tsx @@ -172,6 +172,16 @@ async function uploadBlobAsImage(blob: Blob, name: string): Promise void ): Promise { - const pdfjs = await import('pdfjs-dist'); + // Log step-by-step nella console del browser per poter diagnosticare un fallimento. + // Apri DevTools → Console e filtra per "[pdf]" per vedere ogni passo. + const log = (msg: string, extra?: unknown) => { + if (extra !== undefined) console.info(`[pdf] ${msg}`, extra); + else console.info(`[pdf] ${msg}`); + }; + + log(`start: file="${file.name}", size=${(file.size / 1024).toFixed(1)} KB, type="${file.type}"`); + + let pdfjs; + try { + pdfjs = await import('pdfjs-dist'); + log(`pdfjs-dist imported`); + } catch (err) { + throw new Error(`Could not load the PDF library (pdfjs-dist). ${(err as Error).message}`); + } + // Worker file is copied to /public via the postinstall script. Must include the // basePath so the browser can find it when the app is mounted under /cards. - pdfjs.GlobalWorkerOptions.workerSrc = withBasePath('/pdf.worker.min.mjs'); + const workerUrl = withBasePath('/pdf.worker.min.mjs'); + pdfjs.GlobalWorkerOptions.workerSrc = workerUrl; + log(`worker set to ${workerUrl}`); const arrayBuffer = await file.arrayBuffer(); - const pdf = await pdfjs.getDocument({ data: arrayBuffer }).promise; + log(`file loaded into memory (${arrayBuffer.byteLength} bytes)`); + + let pdf; + try { + pdf = await pdfjs.getDocument({ data: arrayBuffer }).promise; + } catch (err) { + // getDocument fallisce per: worker non raggiungibile (404), PDF cifrato, PDF malformato. + throw new Error(`Could not open the PDF (pdfjs getDocument failed): ${(err as Error).message}. The PDF may be encrypted, corrupted, or the pdf.worker file may not be reachable at ${workerUrl}.`); + } + log(`PDF opened: ${pdf.numPages} pages`); + const baseName = file.name.replace(/\.pdf$/i, '').replace(/[^a-zA-Z0-9-_]/g, '_'); const items: MediaItem[] = []; for (let i = 1; i <= pdf.numPages; i++) { + log(`page ${i}/${pdf.numPages}: rendering...`); onProgress(i, pdf.numPages); - const page = await pdf.getPage(i); - const viewport = page.getViewport({ scale: 1.5 }); - const canvas = document.createElement('canvas'); - canvas.width = viewport.width; - canvas.height = viewport.height; - const ctx = canvas.getContext('2d'); - if (!ctx) continue; - await page.render({ canvasContext: ctx, viewport }).promise; - - const blob: Blob = await new Promise((resolve, reject) => { - canvas.toBlob(b => b ? resolve(b) : reject(new Error('toBlob failed')), 'image/png'); - }); - - const url = await uploadBlobAsImage(blob, `${baseName}-page${i}.png`); - if (url) items.push({ url }); + try { + const page = await pdf.getPage(i); + const viewport = page.getViewport({ scale: 1.5 }); + const canvas = document.createElement('canvas'); + canvas.width = viewport.width; + canvas.height = viewport.height; + const ctx = canvas.getContext('2d'); + if (!ctx) { + log(`page ${i}: skipped — could not get 2D canvas context`); + continue; + } + await page.render({ canvasContext: ctx, viewport }).promise; + log(`page ${i}: rendered (${viewport.width}x${viewport.height})`); + + const blob: Blob = await new Promise((resolve, reject) => { + canvas.toBlob(b => b ? resolve(b) : reject(new Error('canvas.toBlob returned null (PNG encoding failed)')), 'image/png'); + }); + log(`page ${i}: encoded to PNG (${(blob.size / 1024).toFixed(1)} KB)`); + + const url = await uploadBlobAsImage(blob, `${baseName}-page${i}.png`); + if (url) { + log(`page ${i}: uploaded → ${url}`); + items.push({ url }); + } else { + log(`page ${i}: upload returned no URL (server response had no .url field — check the /api/upload network response)`); + } + } catch (err) { + // Propaga ma con contesto sulla pagina specifica così l'utente vede DOVE. + throw new Error(`Failed on page ${i}: ${(err as Error).message}`); + } } + log(`finished: ${items.length} pages uploaded successfully`); return items; } @@ -505,9 +560,18 @@ export default function AdminDashboard() { } } } catch (err) { - console.error('Upload failed for', file.name, err); - const reason = (err as Error)?.message || 'unknown error'; - showToast(`Failed to process "${file.name}": ${reason}. Check the browser console for details.`, 'error'); + // Dump completo nella console (stack incluso) per il debug step-by-step + // visibile in DevTools → Console. L'utente vede invece la causa nel toast. + const e = err as Error; + console.error(`[upload] Failed to process "${file.name}"`); + console.error(`[upload] Message: ${e?.message ?? '(no message)'}`); + console.error(`[upload] Stack:`, e?.stack ?? '(no stack)'); + console.error(`[upload] Raw error object:`, err); + const reason = e?.message || 'unknown error'; + showToast( + `Failed to process "${file.name}": ${reason}. Open DevTools (F12) → Console and filter by "[pdf]" or "[upload]" to see step-by-step diagnostics.`, + 'error', + ); setPdfProgress(null); } }