Przejdź do głównej zawartości

Rozwiązywanie problemów z Artisan

Każda awaria mostka jest zgłaszana jako wyjątek określonego typu. Dopasuj wyjątek i komunikat do poniższego zestawienia. Każdy wpis wskazuje kontrolę w kodzie źródłowym, która go zgłosiła, dzięki czemu można usunąć przyczynę, a nie tylko objaw.

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

Biblioteka kliencka Chrome DevTools Protocol (CDP) nie jest dostępna w autoloaderze. BrowserPool::getBrowser() zgłasza ten wyjątek, zanim Chrome zostanie uruchomiony. Uruchom polecenie instalacji. To inna sytuacja niż brakujący plik binarny: kontrola biblioteki i kontrola pliku binarnego odbywają się na osobnych etapach.

ChromeRenderException — uruchomienie lub przekroczenie limitu czasu

Dział zatytułowany „ChromeRenderException — uruchomienie lub przekroczenie limitu czasu”

Chrome renderer failed: <cause>

Chrome nie mógł się uruchomić, przekroczył limit czasu albo uległ awarii. Poprzedni wyjątek zawiera pierwotną przyczynę. Sprawdź następujące typowe przyczyny:

  • Nie znaleziono pliku binarnego / brak uprawnień do wykonania. Zweryfikuj go za pomocą chromium --headless --dump-dom about:blank. Ustaw chrome_binary na ścieżkę bezwzględną.
  • Piaskownica nie może się zainicjować (kontenery). W przyczynie pojawia się wzmianka o piaskownicy lub przestrzeni nazw. Jeśli to możliwe, użyj kontenera z obsługą piaskownicy albo ustaw no_sandbox: true po zapoznaniu się z /integrations/artisan/security-and-operations/.
  • Przekroczenie limitu czasu. Duży dokument przekroczył render_timeout. Zwiększ limit czasu dla tego obciążenia albo zmniejsz dokument. W ścieżce dostępnej dla użytkownika uwzględnij kompromis względem ryzyka ataku typu „odmowa usługi”.
  • Brakujące biblioteki współdzielone. Chrome zamyka się natychmiast. Zainstaluj zestaw zależności Chrome odpowiedni dla swojej dystrybucji.

Chrome printToPDF returned empty data

Chrome uruchomił się, ale printToPDF zwrócił zero bajtów. Zwykle przyczyną są dane wejściowe, które nie tworzą żadnego renderowanego pola, na przykład pusty element body albo treść z ustawieniem display:none; możliwa jest też awaria Chrome podczas drukowania. Upewnij się, że dane wejściowe w języku Hypertext Markup Language (HTML) renderują się do widocznego pola. Sprawdź obciążenie pamięci hosta.

RuntimeException — dane wejściowe odrzucone przed uruchomieniem Chrome

Dział zatytułowany „RuntimeException — dane wejściowe odrzucone przed uruchomieniem Chrome”
Komunikat zawieraPrzyczynaRozwiązanie
exceeds maximum allowed sizeHTML przekracza maxHtmlSizeZmniejsz dane wejściowe lub zwiększ max_html_size (poszerza powierzchnię ataku przez wyczerpanie zasobów)
oversized base64 data URIOsadzony identyfikator URI (Uniform Resource Identifier) typu data zawierający dane base64 ≥ 13 MBZmniejsz osadzony zasób; użyj odwołania do mniejszego obrazu
forbidden meta refresh redirectObecny <meta http-equiv="refresh">Usuń ten znacznik; to wektor nawigacji typu server-side request forgery (SSRF), który jest zawsze odrzucany

Te błędy pochodzą z ChromeSecurityPolicy::validate() i są zgłaszane przed kontaktem z Chrome, więc obejmowanie ich testami jest szybkie i tanie.

Page <n> has no content stream

Chrome wygenerował plik w formacie Portable Document Format (PDF), ale parser nie mógł wyodrębnić z niego strony. To rzadki przypadek i zwykle wskazuje na nieprawidłowe dane wyjściowe Chrome lub wersję Chrome o nieoczekiwanej strukturze. Zanotuj wersję Chrome oraz dane wejściowe. Sprawdź, czy plik binarny jest obsługiwaną kompilacją Chrome/Chromium.

To nie jest błąd. Mostek blokuje pobieranie każdego podzasobu za pomocą Content Security Policy (CSP) default-src 'none' oraz blokady CDP setBlockedURLs('*'). Zdalne elementy <img>, arkusze stylów, czcionki, skrypty i ramki iframe nie są wczytywane. Osadzaj zasoby jako identyfikatory URI data:, a arkusze stylów Cascading Style Sheets (CSS) przez defaultCss lub <style>. Zobacz model sieciowy na stronie /integrations/artisan/security-and-operations/.

Dokument przekroczył pierwszą stronę Chrome i przeszedł na drugą, a mostek zaimportował tylko stronę 0. Albo bufor automatycznego dopasowania był zbyt mały dla nietypowo dużego ponownego układu treści, albo jawnie podana wysokość była zbyt mała. Ustaw jawną wysokość dopasowaną do treści albo usuń jawnie podaną wysokość, aby użyć automatycznego dopasowania z jego buforem bezpieczeństwa. Zobacz obsługę wysokości na stronie /integrations/artisan/production-usage/.

To oczekiwane zachowanie. BrowserPool ponownie uruchamia Chrome co 100 renderowań, aby ograniczyć zużycie pamięci. Wpis dziennika na poziomie notice rejestruje ponowne uruchomienie oraz liczbę renderowań. Uwzględnij to jako znany okresowy koszt w celach poziomu usług (SLO), a nie jako incydent. Ponowne uruchomienia częstsze niż co 100 renderowań oznaczają, że dokumenty są cięższe, niż oczekiwano.

BrowserPool ogranicza wzrost dzięki ponownemu uruchomieniu co 100 renderowań, ale bardzo długo działający proces roboczy nadal może akumulować zużycie pamięci. Wywołuj close() między dużymi partiami, aby wcześniej odświeżać Chrome, i uruchamiaj proces roboczy z limitem pamięci hosta.

  1. Odtwórz problem za pomocą minimalnego, zaufanego fragmentu HTML, aby oddzielić problemy z danymi wejściowymi od problemów środowiskowych.
  2. Uruchom chromium --headless --dump-dom about:blank na hoście jako użytkownik procesu roboczego.
  3. Wstrzyknij logger zgodny z PHP Standards Recommendation 3 (PSR-3) i odczytaj wpisy info/notice, w tym ścieżkę pliku binarnego i liczbę ponownych uruchomień.
  4. Potwierdź, że chrome-php/chrome jest zainstalowany: BrowserPool::getBrowser() nie zgłosi ChromeNotAvailableException, gdy pakiet jest dostępny.
  5. Sprawdź poprzedni wyjątek dla danego wyjątku, aby poznać podstawową przyczynę po stronie Chrome.
  • /integrations/artisan/install/
  • /integrations/artisan/configuration/
  • /integrations/artisan/security-and-operations/
  • /integrations/artisan/chrome-renderer-setup/
  • /integrations/artisan/production-usage/