Dépannage
Le pont peut déclencher trois types d’exceptions. Celle que tu interceptes t’indique ce qui a échoué et si une nouvelle tentative ou un repli est approprié. Chaque fragment de message ci-dessous est repris exactement du code source.
La hiérarchie des exceptions
Section intitulée « La hiérarchie des exceptions »| Exception | Étend | Signification |
|---|---|---|
CloudflareNotAvailableException | NextPDF\Exception\NextPdfException | L’edge n’a pas pu être joint ou la configuration est incomplète, et aucun repli exploitable n’est disponible. |
CloudflareRenderException | NextPDF\Exception\NextPdfException | Le Worker a répondu, mais le rendu a échoué (erreur HTTP ou corps mal formé). Aucun repli n’est effectué. |
InvalidSpkiPinException | InvalidArgumentException | Une chaîne d’épinglage SPKI configurée est mal formée. |
CloudflareSecurityPolicy peut aussi déclencher directement RuntimeException en cas de violation des règles d’entrée ou d’URL. Cela se produit avant l’envoi de toute requête.
Défaillances de configuration et d’entrée
Section intitulée « Défaillances de configuration et d’entrée »| Fragment de message | Déclenchée par | Cause | Correctif |
|---|---|---|---|
incomplete (missing worker_url or api_token) | Moteur de rendu (via le chemin de repli) | workerUrl ou apiToken vide | Renseigne les deux ; vérifie avec isValid(). |
HTML input exceeds maximum size | CloudflareSecurityPolicy::validate() | Entrée HTML plus longue que maxHtmlSize | Réduis l’entrée ou augmente maxHtmlSize de façon intentionnelle. |
Base64 data URI exceeds safety limit | CloudflareSecurityPolicy::validate() | Une URI data:;base64, dont la taille estimée dépasse 13631488 octets | Externalise la ressource ; n’intègre pas de gros binaires en ligne. |
meta-refresh redirect which could cause SSRF | CloudflareSecurityPolicy::validate() | Une balise <meta http-equiv="refresh"> | Supprime la balise ; utilise une redirection côté serveur en dehors du HTML rendu. |
Invalid Worker URL | validateWorkerUrl() | L’URL ne peut pas être analysée ou n’a pas de scheme/host | Fournis une URL HTTPS absolue et complète. |
Worker URL must use HTTPS | validateWorkerUrl() | Schéma autre que HTTPS | Utilise https://. |
private or reserved IP addresses | validateWorkerUrl() | Adresse IP littérale dans la plage RFC 1918 / loopback / RFC 3927 | Pointe vers un point de terminaison public. |
hostname resolves to a private or reserved IP | validateWorkerUrl() | Un enregistrement A/AAAA résout vers une adresse private/reserved | Corrige le DNS ; recherche un éventuel rebinding. |
DNS answer changed since validation | assertPinsStillValid() | L’hôte a été résolu vers une nouvelle IP entre la vérification et l’envoi | Résous à nouveau ; traite cela comme une possible tentative de rebinding. |
Défaillances côté Worker
Section intitulée « Défaillances côté Worker »Ce sont des CloudflareRenderException. Le Worker a répondu, mais le rendu lui-même a échoué. Elles ne déclenchent jamais le repli local — l’edge était joignable.
| Fragment de message | Cause |
|---|---|
Cloudflare Worker returned HTTP <code>: <detail> | Statut différent de 200. Le détail vient du champ JSON error ou des 200 premiers octets du corps. |
Worker returned empty or invalid PDF data | Réponse binaire ne commençant pas par %PDF. |
Worker error: <message> | Réponse JSON contenant un champ error. |
JSON response missing "pdf" field | Réponse JSON sans champ pdf. |
Invalid base64-encoded PDF in JSON response | Le champ pdf ne peut pas être décodé depuis base64 en octets commençant par %PDF. |
Invalid JSON response from Worker | Content-Type: application/json, mais le corps ne se décode pas en tableau. |
Unexpected Content-Type from Worker: <type> | Réponse 200 dont le Content-Type n’est ni application/pdf ni application/json. |
Si tu interceptes l’une de ces exceptions, examine les journaux du Worker. La défaillance se situe côté Worker, pas dans ce pont.
Défaillances de joignabilité et de repli
Section intitulée « Défaillances de joignabilité et de repli »Ce sont des CloudflareNotAvailableException. L’edge n’a pas pu être utilisé et aucun repli n’a produit de PDF.
| Fragment de message | Cause | Correctif |
|---|---|---|
Cloudflare Worker unavailable: <reason> | Erreur de transport, repli désactivé | Active fallbackToLocal et fournis une fabrique, ou corrige la connectivité. |
Artisan is installed but no LocalRendererFactoryInterface was provided | nextpdf/artisan installé, aucune fabrique fournie | Transmets une LocalRendererFactoryInterface au constructeur. |
local Chrome fallback (nextpdf/artisan) is not installed | Repli activé, aucune fabrique fournie, Artisan absent | composer require nextpdf/artisan et fournis une fabrique. |
Quand tu fournis un journaliseur PSR-3 et que le chemin de repli s’exécute, le pont consigne un warning (Cloudflare render failed, attempting fallback), puis un info (Falling back to local renderer).
Défaillances de transport / d’épinglage
Section intitulée « Défaillances de transport / d’épinglage »| Symptôme | Cause | Correctif |
|---|---|---|
InvalidSpkiPinException: Invalid SPKI pin format | Une valeur d’épinglage qui n’est pas au format sha256/<base64> (ou sha256//<base64>) | Corrige la chaîne d’épinglage. |
cURL transport error (<n>): <msg> | Défaillance au niveau de cURL (TLS, DNS, délai d’attente dépassé) | Examine le numéro d’erreur cURL ; si des épinglages sont configurés, confirme que le SPKI servi est toujours épinglé. |
| Les rendus échouent immédiatement après une rotation de certificat | Le SPKI du nouveau certificat ne figure pas dans l’ensemble d’épinglages | Ajoute le nouveau SPKI comme épinglage de secours avant la rotation. |
| Le transport épinglé n’est pas utilisé alors que des épinglages sont configurés | Aucune ResponseFactory PSR-17 fournie | Transmets une ResponseFactory ; le transport épinglé l’exige. |
Comportement de isAvailable()
Section intitulée « Comportement de isAvailable() »isAvailable() ne lève jamais d’exception. La méthode renvoie false lorsque la configuration est invalide, ou lorsque la sonde HEAD échoue ou lève une exception. Elle ne renvoie true que lorsque la sonde répond avec un statut inférieur à 500. Un résultat true reste une indication : le POST qui suit peut toujours échouer avec l’une des erreurs côté Worker ci-dessus. Ne considère pas une sonde réussie comme une garantie.
Surprises liées à la limitation de débit
Section intitulée « Surprises liées à la limitation de débit »Le limiteur ApiProtection réside en mémoire, par processus. Ses compteurs ne survivent pas à un redémarrage et ne sont pas partagés entre les workers ou les nœuds. Il est donc normal de voir un client autorisé sur un nœud et refusé sur un autre. Utilise un magasin partagé en amont du limiteur pour obtenir une limite à l’échelle du cluster.
Voir aussi
Section intitulée « Voir aussi »- /integrations/cloudflare/security-and-operations/ — le runbook opérationnel et les contrôles à l’origine de ces messages.
- /integrations/cloudflare/quickstart/ — la forme canonique du try/catch.
- /integrations/cloudflare/production-usage/ — détails pour brancher le repli.