Pular para o conteúdo

Solução de problemas no Artisan

Toda falha da ponte aparece como uma exceção tipada. Relacione a exceção e a mensagem à tabela abaixo. Cada linha aponta para a verificação de origem que a acionou, para que você corrija a causa, não apenas o sintoma.

chrome-php/chrome is not installed. Install it via: composer require chrome-php/chrome:^1.15

A biblioteca cliente do Chrome DevTools Protocol (CDP) não está no autoloader. BrowserPool::getBrowser() dispara essa exceção antes de iniciar o Chrome. Execute o comando de instalação. Isso é diferente de um binário ausente: a verificação da biblioteca e a verificação do binário são executadas em etapas separadas.

ChromeRenderException — inicialização ou tempo limite

Seção intitulada “ChromeRenderException — inicialização ou tempo limite”

Chrome renderer failed: <cause>

O Chrome não conseguiu iniciar, atingiu o tempo limite ou travou. A exceção anterior contém a causa original. Verifique estas causas comuns:

  • Binário não encontrado / não executável. Verifique com chromium --headless --dump-dom about:blank. Defina chrome_binary com o caminho absoluto.
  • O sandbox não consegue inicializar (containers). A causa menciona o sandbox ou o namespace. Use um container com suporte a sandbox quando possível ou defina no_sandbox: true depois de ler /integrations/artisan/security-and-operations/.
  • Tempo limite. Um documento pesado excedeu render_timeout. Aumente o tempo limite para essa carga de trabalho ou reduza o documento. Em um caminho exposto ao usuário, pondere o impacto sobre negação de serviço.
  • Bibliotecas compartilhadas ausentes. O Chrome encerra imediatamente. Instale o conjunto de dependências do Chrome para a sua distribuição.

Chrome printToPDF returned empty data

O Chrome iniciou, mas printToPDF retornou zero bytes. A causa mais comum é uma entrada que não cria nenhuma caixa renderizada, como um body vazio ou conteúdo definido como display:none, ou uma falha do Chrome durante a impressão. Confirme que a entrada em Hypertext Markup Language (HTML) renderiza uma caixa visível. Verifique também a pressão de memória do host.

RuntimeException — entrada rejeitada antes do Chrome

Seção intitulada “RuntimeException — entrada rejeitada antes do Chrome”
A mensagem contémCausaCorreção
exceeds maximum allowed sizeO HTML excede maxHtmlSizeReduza a entrada ou aumente max_html_size (amplia a superfície de esgotamento de recursos)
oversized base64 data URIURI (Uniform Resource Identifier) de dados em base64 embutida ≥ 13 MBReduza o recurso embutido; referencie uma imagem menor
forbidden meta refresh redirect<meta http-equiv="refresh"> presenteRemova a tag; ela é um vetor de navegação para server-side request forgery (SSRF) e é sempre rejeitada

Esses erros vêm de ChromeSecurityPolicy::validate() e disparam antes que o Chrome seja contatado, portanto são rápidos e baratos de cobrir em testes.

Page <n> has no content stream

O Chrome produziu um arquivo em Portable Document Format (PDF) do qual o parser não conseguiu extrair uma página. Isso é raro e geralmente indica uma saída malformada do Chrome ou uma versão do Chrome com estrutura inesperada. Capture a versão do Chrome e a entrada. Verifique se o binário é um build de Chrome/Chromium compatível.

Isso não é um bug. A ponte bloqueia toda busca de sub-recurso com a Content Security Policy (CSP) default-src 'none' e um bloqueio CDP setBlockedURLs('*'). <img> remotos, folhas de estilo, fontes, scripts e iframes não carregam. Embuta os recursos como URIs data: e inclua o Cascading Style Sheets (CSS) por meio de defaultCss ou <style>. Veja o modelo de rede em /integrations/artisan/security-and-operations/.

O documento transbordou para uma segunda página do Chrome, e a ponte importou apenas a página 0. Ou o buffer de auto-ajuste foi pequeno demais para um refluxo excepcionalmente grande, ou uma altura explícita foi pequena demais. Defina uma altura explícita adequada ao conteúdo ou remova a altura explícita para usar o auto-ajuste com seu buffer de segurança. Veja o tratamento de altura em /integrations/artisan/production-usage/.

Isso é esperado. O BrowserPool reinicia o Chrome a cada 100 renderizações para limitar a memória. Uma linha de log no nível notice registra o reinício e a contagem de renderizações. Trate isso como um custo periódico conhecido nos objetivos de nível de serviço (SLOs), não como um incidente. Se os reinícios ocorrerem com mais frequência do que a cada 100 renderizações, os documentos são mais pesados do que o esperado.

BrowserPool limita o crescimento com o reinício a cada 100 renderizações, mas um worker com vida muito longa ainda pode acumular memória. Chame close() entre lotes grandes para reciclar o Chrome antecipadamente e execute o worker sob um limite de memória do host.

  1. Reproduza com um fragmento de HTML mínimo e confiável para separar problemas de entrada de problemas de ambiente.
  2. Execute chromium --headless --dump-dom about:blank no host, como o usuário do worker.
  3. Injete um logger PHP Standards Recommendation 3 (PSR-3) e leia as linhas info/notice, incluindo o caminho do binário e a contagem de reinícios.
  4. Confirme que chrome-php/chrome está instalado: BrowserPool::getBrowser() não lançará ChromeNotAvailableException quando ele estiver disponível.
  5. Verifique a exceção anterior para identificar a causa subjacente do Chrome.
  • /integrations/artisan/install/
  • /integrations/artisan/configuration/
  • /integrations/artisan/security-and-operations/
  • /integrations/artisan/chrome-renderer-setup/
  • /integrations/artisan/production-usage/