Перейти к содержимому

Устранение неполадок

Мост вызывает три типа исключений. По перехваченному исключению понятно, что именно отказало и нужно ли повторить попытку или перейти на резервный путь. Каждый фрагмент сообщения ниже взят из исходного кода.

ИсключениеНаследуетЗначение
CloudflareNotAvailableExceptionNextPDF\Exception\NextPdfExceptionМост не может обратиться к периферии или конфигурация неполна, а пригодного резервного пути нет.
CloudflareRenderExceptionNextPDF\Exception\NextPdfExceptionWorker ответил, но отрисовка не удалась (ошибка Hypertext Transfer Protocol (HTTP) или некорректное тело). Резервный путь никогда не запускается.
InvalidSpkiPinExceptionInvalidArgumentExceptionНастроенная строка пина Subject Public Key Info (SPKI) имеет неверный формат.

CloudflareSecurityPolicy также напрямую вызывает RuntimeException при нарушениях политики для входных данных и Uniform Resource Locator (URL). Исключение возникает до отправки любого запроса.

Фрагмент сообщенияВызываетсяПричинаРешение
incomplete (missing worker_url or api_token)renderer (по резервному пути)workerUrl или apiToken пустЗадайте оба значения, затем проверьте их через isValid().
HTML input exceeds maximum sizeCloudflareSecurityPolicy::validate()Входные данные Hypertext Markup Language (HTML) длиннее maxHtmlSizeУменьшите объём входных данных или осознанно увеличьте maxHtmlSize.
Base64 data URI exceeds safety limitCloudflareSecurityPolicy::validate()Расчётный размер Uniform Resource Identifier (URI) вида data:;base64, превышает 13631488 байтВынесите ресурс наружу; не встраивайте крупные бинарные данные.
meta-refresh redirect which could cause SSRFCloudflareSecurityPolicy::validate()Тег <meta http-equiv="refresh"> может спровоцировать подделку запроса на стороне сервера (SSRF)Удалите тег; используйте серверное перенаправление за пределами отрисовываемого HTML.
Invalid Worker URLvalidateWorkerUrl()URL не разбирается или в нём нет scheme/hostУкажите полный абсолютный URL с Hypertext Transfer Protocol Secure (HTTPS).
Worker URL must use HTTPSvalidateWorkerUrl()Схема не HTTPSИспользуйте https://.
private or reserved IP addressesvalidateWorkerUrl()IP-литерал Internet Protocol (IP) в диапазоне Request for Comments (RFC) 1918 / loopback / RFC 3927Укажите публичную конечную точку.
hostname resolves to a private or reserved IPvalidateWorkerUrl()Разрешённая запись A/AAAA системы доменных имён Domain Name System (DNS) является частной или зарезервированнойИсправьте DNS; проверьте возможную атаку перепривязки (rebinding).
DNS answer changed since validationassertPinsStillValid()Между проверкой и отправкой хост разрешился в новый IP-адресПовторите разрешение; рассматривайте это как возможную попытку перепривязки.

Это сбои CloudflareRenderException. Worker ответил, но сама отрисовка не удалась. Они никогда не запускают локальный резервный путь, потому что периферия была доступна.

Фрагмент сообщенияПричина
Cloudflare Worker returned HTTP <code>: <detail>Статус, отличный от 200. Подробности берутся из поля error JavaScript Object Notation (JSON) или из первых 200 байт тела ответа.
Worker returned empty or invalid PDF dataБинарный ответ не начинается с %PDF.
Worker error: <message>Ответ JSON, который содержит поле error.
JSON response missing "pdf" fieldОтвет JSON без поля pdf.
Invalid base64-encoded PDF in JSON responseПосле декодирования из base64 поле pdf не даёт байты, начинающиеся с %PDF.
Invalid JSON response from WorkerТело использует Content-Type: application/json, но не декодируется в массив.
Unexpected Content-Type from Worker: <type>Ответ 200, у которого Content-Type не является ни application/pdf, ни application/json.

Если вы перехватили один из этих сбоев, проверьте журналы Worker. Сбой произошёл на стороне Worker, а не в этом мосте.

Это сбои CloudflareNotAvailableException. Мост не смог воспользоваться периферией, и ни один резервный путь не создал файл Portable Document Format (PDF).

Фрагмент сообщенияПричинаРешение
Cloudflare Worker unavailable: <reason>Ошибка транспорта при отключённом резервном путиВключите fallbackToLocal и подключите фабрику либо исправьте подключение.
Artisan is installed but no LocalRendererFactoryInterface was providednextpdf/artisan установлен, но фабрика не переданаПередайте LocalRendererFactoryInterface в конструктор.
local Chrome fallback (nextpdf/artisan) is not installedРезервный путь включён, фабрика не настроена, и Artisan отсутствуетВыполните composer require nextpdf/artisan, затем подключите фабрику.

Если вы передали журналировщик PHP Standards Recommendation (PSR)-3 и сработал резервный путь, мост записывает warning (Cloudflare render failed, attempting fallback), затем info (Falling back to local renderer).

СимптомПричинаРешение
InvalidSpkiPinException: Invalid SPKI pin formatПин не соответствует форме sha256/<base64> (или sha256//<base64>)Исправьте строку пина.
cURL transport error (<n>): <msg>Сбой на уровне cURL (Transport Layer Security (TLS), DNS, тайм-аут)Проверьте номер ошибки cURL; если пины заданы, убедитесь, что предъявленный SPKI всё ещё закреплён.
Отрисовка сразу же не удаётся после ротации сертификатаSPKI нового сертификата отсутствует в наборе пиновДобавьте новый SPKI как резервный пин до ротации.
Закреплённый транспорт не используется, несмотря на настроенные пиныНе передан ResponseFactory в формате PSR-17Передайте ResponseFactory; закреплённому транспорту он необходим.

isAvailable() никогда не выбрасывает исключение. Он возвращает false, когда конфигурация неверна либо проба HEAD не удаётся или вызывает исключение. Он возвращает true только тогда, когда проба отвечает статусом ниже 500. Результат true — лишь подсказка: последующий POST всё ещё может завершиться любой из приведённых выше ошибок на стороне Worker. Не считайте успешную пробу гарантией.

ApiProtection хранит ограничения в памяти процесса. Счётчики не сохраняются после перезапуска и не разделяются между воркерами или узлами. Если один узел разрешает клиента, а другой ему отказывает, это ожидаемо. Поставьте общее хранилище перед ограничителем, чтобы ограничение работало в масштабе кластера.

  • /integrations/cloudflare/security-and-operations/ — операционное руководство и средства контроля, стоящие за этими сообщениями.
  • /integrations/cloudflare/quickstart/ — канонический шаблон try/catch.
  • /integrations/cloudflare/production-usage/ — детали подключения резервного пути.