Risoluzione dei problemi
In sintesi
Sezione intitolata “In sintesi”Il bridge può sollevare tre tipi di eccezione. L’eccezione intercettata indica che cosa è andato storto e se conviene riprovare o attivare un fallback. Ogni frammento di messaggio riportato di seguito è citato dal codice sorgente.
La gerarchia delle eccezioni
Sezione intitolata “La gerarchia delle eccezioni”| Eccezione | Estende | Significato |
|---|---|---|
CloudflareNotAvailableException | NextPDF\Exception\NextPdfException | Non è stato possibile raggiungere l’edge, oppure la configurazione è incompleta e non esiste alcun fallback utilizzabile. |
CloudflareRenderException | NextPDF\Exception\NextPdfException | Il Worker ha risposto, ma il rendering è fallito (errore HTTP o corpo malformato). Non attiva mai il fallback. |
InvalidSpkiPinException | InvalidArgumentException | Una stringa configurata per il pin SPKI è malformata. |
CloudflareSecurityPolicy solleva inoltre direttamente RuntimeException per le violazioni dei criteri di input e di URL. Lo fa prima che venga inviata qualsiasi richiesta.
Errori di configurazione e di input
Sezione intitolata “Errori di configurazione e di input”| Frammento del messaggio | Sollevata da | Causa | Soluzione |
|---|---|---|---|
incomplete (missing worker_url or api_token) | Renderer (tramite il percorso di fallback) | workerUrl o apiToken vuoto | Impostare entrambi; verificare con isValid(). |
HTML input exceeds maximum size | CloudflareSecurityPolicy::validate() | HTML di lunghezza superiore a maxHtmlSize | Ridurre l’input oppure aumentare maxHtmlSize consapevolmente. |
Base64 data URI exceeds safety limit | CloudflareSecurityPolicy::validate() | Un URI data:;base64, stimato oltre i 13631488 byte | Spostare l’asset all’esterno; non incorporare binari di grandi dimensioni. |
meta-refresh redirect which could cause SSRF | CloudflareSecurityPolicy::validate() | Un tag <meta http-equiv="refresh"> | Rimuovere il tag; usare un redirect lato server al di fuori dell’HTML sottoposto a rendering. |
Invalid Worker URL | validateWorkerUrl() | L’URL non è parsabile oppure è privo di scheme/host | Fornire un URL HTTPS assoluto e completo. |
Worker URL must use HTTPS | validateWorkerUrl() | Schema diverso da HTTPS | Usare https://. |
private or reserved IP addresses | validateWorkerUrl() | Indirizzo IP letterale nell’intervallo RFC 1918 / loopback / RFC 3927 | Puntare a un endpoint pubblico. |
hostname resolves to a private or reserved IP | validateWorkerUrl() | Un record A/AAAA risolto risulta private/reserved | Correggere il DNS; indagare su un possibile rebinding. |
DNS answer changed since validation | assertPinsStillValid() | L’host è stato risolto in un nuovo IP tra il controllo e l’invio | Risolvere di nuovo; considerarlo un possibile tentativo di rebinding. |
Errori lato Worker
Sezione intitolata “Errori lato Worker”Sono casi di CloudflareRenderException. Il Worker ha risposto, ma il rendering stesso è fallito. Questi errori non attivano mai il fallback locale — l’edge era raggiungibile.
| Frammento del messaggio | Causa |
|---|---|
Cloudflare Worker returned HTTP <code>: <detail> | Stato diverso da 200. Il dettaglio proviene dal campo JSON error oppure dai primi 200 byte del corpo. |
Worker returned empty or invalid PDF data | Risposta binaria che non inizia con %PDF. |
Worker error: <message> | Risposta JSON che contiene un campo error. |
JSON response missing "pdf" field | Risposta JSON priva del campo pdf. |
Invalid base64-encoded PDF in JSON response | Il campo pdf non è stato decodificato da base64 in byte che iniziano con %PDF. |
Invalid JSON response from Worker | Content-Type: application/json ma il corpo non è stato decodificato in un array. |
Unexpected Content-Type from Worker: <type> | Uno stato 200 il cui Content-Type non è né application/pdf né application/json. |
Se si intercetta uno di questi errori, ispezionare i log del Worker. L’errore è sul lato Worker, non in questo bridge.
Errori di raggiungibilità e di fallback
Sezione intitolata “Errori di raggiungibilità e di fallback”Sono casi di CloudflareNotAvailableException. Non è stato possibile usare l’edge e nessun fallback ha prodotto un PDF.
| Frammento del messaggio | Causa | Soluzione |
|---|---|---|
Cloudflare Worker unavailable: <reason> | Errore di trasporto, fallback disabilitato | Abilitare fallbackToLocal e collegare una factory, oppure correggere la connettività. |
Artisan is installed but no LocalRendererFactoryInterface was provided | nextpdf/artisan presente, nessuna factory fornita | Passare una LocalRendererFactoryInterface al costruttore. |
local Chrome fallback (nextpdf/artisan) is not installed | Fallback abilitato, nessuna factory, Artisan assente | composer require nextpdf/artisan e collegare una factory. |
Quando viene fornito un logger PSR-3 e viene eseguito il percorso di fallback, il bridge registra prima un warning (Cloudflare render failed, attempting fallback), poi un info (Falling back to local renderer).
Errori di trasporto / pinning
Sezione intitolata “Errori di trasporto / pinning”| Sintomo | Causa | Soluzione |
|---|---|---|
InvalidSpkiPinException: Invalid SPKI pin format | Un pin non nel formato sha256/<base64> (oppure sha256//<base64>) | Correggere la stringa del pin. |
cURL transport error (<n>): <msg> | Errore a livello di cURL (TLS, DNS, timeout) | Controllare il numero di errore cURL; se i pin sono configurati, verificare che l’SPKI servito sia ancora associato al pin. |
| Le operazioni di rendering falliscono immediatamente dopo la rotazione del certificato | L’SPKI del nuovo certificato non è nell’insieme dei pin | Aggiungere il nuovo SPKI come pin di backup prima della rotazione. |
| Il trasporto con pinning non viene usato nonostante i pin siano configurati | Nessuna ResponseFactory PSR-17 fornita | Passare una ResponseFactory; il trasporto con pinning la richiede. |
Comportamento di isAvailable()
Sezione intitolata “Comportamento di isAvailable()”isAvailable() non solleva mai un’eccezione. Restituisce false quando la configurazione non è valida oppure quando la sonda HEAD fallisce o solleva un’eccezione. Restituisce true solo quando la sonda risponde con uno stato inferiore a 500. Un risultato true è solo indicativo: la successiva POST può comunque fallire con uno qualsiasi degli errori lato Worker indicati sopra. Non considerare una sonda riuscita una garanzia.
Comportamenti inattesi del rate limit
Sezione intitolata “Comportamenti inattesi del rate limit”Il limitatore ApiProtection mantiene lo stato in memoria per ogni processo. I conteggi non sopravvivono a un riavvio e non sono condivisi tra worker o nodi. Quindi, se si osserva che un client è consentito su un nodo e negato su un altro, è il comportamento atteso. Inserire uno store condiviso prima del limitatore per ottenere un limite a livello di cluster.
Vedere anche
Sezione intitolata “Vedere anche”- /integrations/cloudflare/security-and-operations/ — il runbook operativo e i controlli che stanno alla base di questi messaggi.
- /integrations/cloudflare/quickstart/ — il modello canonico di try/catch.
- /integrations/cloudflare/production-usage/ — dettagli su come collegare il fallback.