콘텐츠로 이동

문제 해결

이 브리지는 세 가지 유형의 예외를 발생시킵니다. 포착한 예외는 무엇이 실패했는지와 재시도 또는 폴백이 적절한지를 알려줍니다. 아래의 모든 메시지 조각은 소스에서 인용한 것입니다.

예외상속의미
CloudflareNotAvailableExceptionNextPDF\Exception\NextPdfException엣지에 도달할 수 없거나 구성이 불완전하고, 사용 가능한 폴백이 없습니다.
CloudflareRenderExceptionNextPDF\Exception\NextPdfExceptionWorker는 응답했지만 렌더링이 실패했습니다(HTTP 오류 또는 형식이 잘못된 본문). 절대 폴백하지 않습니다.
InvalidSpkiPinExceptionInvalidArgumentException구성된 SPKI 핀 문자열의 형식이 잘못되었습니다.

CloudflareSecurityPolicy는 입력 및 URL 정책 위반이 있으면 RuntimeException도 직접 발생시킵니다. 이는 요청이 전송되기 전에 발생합니다.

메시지 조각발생 위치원인해결 방법
incomplete (missing worker_url or api_token)렌더러(폴백 경로 경유)workerUrl 또는 apiToken이 비어 있음둘 다 설정하고 isValid()로 확인하십시오.
HTML input exceeds maximum sizeCloudflareSecurityPolicy::validate()HTML이 maxHtmlSize보다 큼입력을 줄이거나 maxHtmlSize를 의도적으로 높이십시오.
Base64 data URI exceeds safety limitCloudflareSecurityPolicy::validate()data:;base64, URI가 13631488 바이트를 초과하는 것으로 추정됨자산은 외부로 분리하십시오. 큰 바이너리를 인라인하지 마십시오.
meta-refresh redirect which could cause SSRFCloudflareSecurityPolicy::validate()<meta http-equiv="refresh"> 태그태그를 제거하십시오. 렌더링되는 HTML 외부에서 서버 측 리디렉션을 사용하십시오.
Invalid Worker URLvalidateWorkerUrl()URL이 파싱되지 않거나 scheme/host가 없음완전한 절대 HTTPS URL을 제공하십시오.
Worker URL must use HTTPSvalidateWorkerUrl()HTTPS가 아닌 스킴https://를 사용하십시오.
private or reserved IP addressesvalidateWorkerUrl()RFC 1918 / 루프백 / RFC 3927 범위의 IP 리터럴공용 엔드포인트를 가리키도록 하십시오.
hostname resolves to a private or reserved IPvalidateWorkerUrl()확인된 A/AAAA 레코드가 private/reserved 범위임DNS를 수정하십시오. 리바인딩 가능성을 조사하십시오.
DNS answer changed since validationassertPinsStillValid()확인과 전송 사이에 호스트가 새 IP로 확인되었음다시 확인하십시오. 가능한 리바인딩 시도로 취급하십시오.

이는 CloudflareRenderException입니다. Worker는 응답했지만 렌더링 자체가 실패한 경우입니다. 이 경우에는 로컬 폴백이 절대 트리거되지 않습니다 — 엣지에는 도달할 수 있었기 때문입니다.

메시지 조각원인
Cloudflare Worker returned HTTP <code>: <detail>200이 아닌 상태입니다. 세부 정보는 JSON error 필드 또는 본문 처음 200 바이트입니다.
Worker returned empty or invalid PDF data%PDF로 시작하지 않는 바이너리 응답입니다.
Worker error: <message>error 필드를 포함한 JSON 응답입니다.
JSON response missing "pdf" fieldpdf 필드가 없는 JSON 응답입니다.
Invalid base64-encoded PDF in JSON responsepdf 필드의 base64 디코딩 결과가 %PDF로 시작하는 바이트가 아닙니다.
Invalid JSON response from WorkerContent-Type: application/json이지만 본문이 배열로 디코딩되지 않았습니다.
Unexpected Content-Type from Worker: <type>Content-Type이 application/pdfapplication/json도 아닌 200입니다.

이 중 하나를 포착했다면 Worker 로그를 검사하십시오. 실패 원인은 이 브리지가 아니라 Worker 측에 있습니다.

이는 CloudflareNotAvailableException입니다. 엣지를 사용할 수 없었고, 어떤 폴백도 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을 실행하고 팩토리를 연결하십시오.

PSR-3 로거를 제공하고 폴백 경로가 실행되면 브리지는 warning(Cloudflare render failed, attempting fallback)을 기록한 다음 info(Falling back to local renderer)를 기록합니다.

증상원인해결 방법
InvalidSpkiPinException: Invalid SPKI pin formatsha256/<base64>(또는 sha256//<base64>) 형식이 아닌 핀핀 문자열을 수정하십시오.
cURL transport error (<n>): <msg>cURL 수준 실패(TLS, DNS, 타임아웃)cURL 오류 번호를 검사하십시오. 핀이 설정되어 있다면, 제공된 SPKI가 여전히 핀에 고정되어 있는지 확인하십시오.
인증서 교체 직후 렌더링이 즉시 실패함새 인증서의 SPKI가 핀 세트에 없음교체하기 전에 새 SPKI를 백업 핀으로 추가하십시오.
핀이 구성되어 있는데도 핀 고정 전송이 사용되지 않음PSR-17 ResponseFactory가 제공되지 않음ResponseFactory를 전달하십시오. 핀 고정 전송에는 이것이 필요합니다.

isAvailable()은 절대 예외를 던지지 않습니다. 구성이 유효하지 않거나 HEAD 프로브가 실패하거나 예외를 발생시키면 false를 반환합니다. 프로브가 500 미만의 상태 코드로 응답할 때만 true를 반환합니다. true 결과는 힌트일 뿐입니다. 이후 POST는 위의 Worker 측 오류 중 어떤 것으로도 여전히 실패할 수 있습니다. 통과한 프로브를 보장으로 취급하지 마십시오.

ApiProtection 제한기는 프로세스별 인메모리 방식입니다. 카운트는 재시작 후 유지되지 않으며, 워커나 노드 간에 공유되지 않습니다. 따라서 어떤 클라이언트가 한 노드에서는 허용되고 다른 노드에서는 거부되는 것을 보더라도 이는 예상된 동작입니다. 클러스터 전체에 적용되는 제한이 필요하면 제한기 앞에 공유 저장소를 두십시오.

  • /integrations/cloudflare/security-and-operations/ — 운영 런북과 이러한 메시지의 근거가 되는 제어 장치입니다.
  • /integrations/cloudflare/quickstart/ — 표준 try/catch 형태입니다.
  • /integrations/cloudflare/production-usage/ — 폴백 연결 방식의 세부 정보입니다.