تخطَّ إلى المحتوى

استكشاف أخطاء Artisan وإصلاحها

يظهر كل فشل في الجسر على هيئة استثناء مُصنَّف. طابِق الاستثناء والرسالة مع الجدول أدناه. يشير كل صف إلى فحص المصدر الذي أطلقه، حتى تتمكن من معالجة السبب لا العَرَض.

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

مكتبة عميل بروتوكول ⁨Chrome DevTools⁩‏ (⁨CDP⁩) غير موجودة في المُحمِّل التلقائي. يُطلق BrowserPool::getBrowser() هذا الاستثناء قبل تشغيل ⁨Chrome.⁩ شغّل أمر التثبيت. يختلف ذلك عن الملف الثنائي المفقود: يُنفَّذ فحص المكتبة وفحص الملف الثنائي في مرحلتين منفصلتين.

ChromeRenderException — التشغيل أو انتهاء المهلة

قسم بعنوان «ChromeRenderException — التشغيل أو انتهاء المهلة»

Chrome renderer failed: <cause>

تعذّر بدء تشغيل ⁨Chrome⁩، أو انتهت مهلته، أو تعطّل. يحتوي الاستثناء السابق على السبب الأصلي. تحقّق من الأسباب الشائعة التالية:

  • الملف الثنائي غير موجود / غير قابل للتنفيذ. تحقّق منه باستخدام chromium --headless --dump-dom about:blank. عيّن chrome_binary إلى المسار المطلق.
  • تعذّر تهيئة البيئة المعزولة (الحاويات). يذكر السبب البيئة المعزولة أو مساحة الأسماء. استخدم حاوية تدعم البيئة المعزولة متى أمكن، أو عيّن no_sandbox: true بعد قراءة /⁨integrations/artisan/security-and-operations/.⁩
  • انتهاء المهلة. تجاوز مستند ثقيل قيمة render_timeout. ارفع المهلة لذلك الحِمل، أو قلّص المستند. في مسار موجَّه للمستخدم، وازِن ذلك مقابل خطر حجب الخدمة.
  • مكتبات مشتركة مفقودة. يخرج ⁨Chrome⁩ فوراً. ثبّت حزمة تبعيات ⁨Chrome⁩ المناسبة لتوزيعتك.

Chrome printToPDF returned empty data

بدأ ⁨Chrome⁩، لكن printToPDF أعاد صفر بايت. السبب المعتاد هو دخل لا يُنشئ أي صندوق معروض، مثل متن فارغ أو محتوى مضبوط على display:none، أو تعطُّل ⁨Chrome⁩ أثناء الطباعة. تأكّد من أن دخل ⁨HTML⁩ يُعرَض داخل صندوق مرئي. تحقّق من ضغط الذاكرة على المضيف.

RuntimeException — رُفِض الدخل قبل ⁨Chrome⁩

قسم بعنوان «RuntimeException — رُفِض الدخل قبل ⁨Chrome⁩»
تحتوي الرسالة علىالسببالإصلاح
exceeds maximum allowed sizeيتجاوز ⁨HTML⁩ قيمة maxHtmlSizeقلّص الدخل أو ارفع max_html_size (يوسّع سطح استنزاف الموارد)
oversized base64 data URI⁨URI⁩ مضمَّن من نوع ⁨base64 data⁩ بحجم ≥ 13 ⁨MB⁩قلّص الأصل المضمَّن، أو أشِر إلى صورة أصغر
forbidden meta refresh redirect<meta http-equiv="refresh"> موجودأزِل الوسم؛ فهو متجه تنقّل لتزوير الطلب من جانب الخادم (⁨SSRF⁩) ويُرفَض دائماً

تأتي هذه الأخطاء من ChromeSecurityPolicy::validate() وتُطلق قبل الاتصال بـ ⁨Chrome⁩، لذلك تكون سريعة ومنخفضة التكلفة عند تغطيتها بالاختبارات.

Page <n> has no content stream

أنتج ⁨Chrome⁩ ملف ⁨PDF⁩ لم يتمكّن المُحلِّل من استخراج صفحة منه. هذا نادر، وعادةً ما يشير إلى مُخرَج ⁨Chrome⁩ مُشوَّه أو إلى إصدار ⁨Chrome⁩ ببنية غير متوقَّعة. سجّل إصدار ⁨Chrome⁩ والدخل. تحقّق من أن الملف الثنائي هو إصدار ⁨Chrome/Chromium⁩ مدعوم.

الأصول البعيدة تُعرَض فارغة

قسم بعنوان «الأصول البعيدة تُعرَض فارغة»

هذا ليس خطأً برمجياً. يحجب الجسر كل جلب لمورد فرعي عبر سياسة أمان المحتوى (⁨CSP⁩) default-src 'none' وحجب ⁨CDP⁩ عبر setBlockedURLs('*'). لا تُحمَّل عناصر <img> البعيدة ولا أوراق الأنماط ولا الخطوط ولا البرامج النصية ولا الإطارات المضمَّنة. ضمِّن الأصول على هيئة معرّفات ⁨URI⁩ من نوع data:، وضمِّن ⁨CSS⁩ عبر defaultCss أو <style>. راجِع نموذج الشبكة في /⁨integrations/artisan/security-and-operations/.⁩

امتدّ المستند إلى صفحة ⁨Chrome⁩ ثانية، واستورد الجسر الصفحة 0 فقط. إمّا أن مخزّن الملاءمة التلقائية كان أصغر من اللازم لإعادة تدفّق طويلة بشكل غير معتاد، أو أن ارتفاعاً صريحاً كان أصغر من اللازم. عيّن ارتفاعاً صريحاً بحجم المحتوى، أو أزِل الارتفاع الصريح لاستخدام الملاءمة التلقائية مع مخزّن الأمان الخاص بها. راجِع معالجة الارتفاع في /⁨integrations/artisan/production-usage/.⁩

ارتفاع مفاجئ في الكمون كل ~100 عملية عرض

قسم بعنوان «ارتفاع مفاجئ في الكمون كل ~100 عملية عرض»

هذا متوقَّع. يُعيد BrowserPool تشغيل ⁨Chrome⁩ كل 100 عملية عرض لتقييد الذاكرة. يُسجّل سطر سجل بمستوى notice إعادة التشغيل وعدد عمليات العرض. تعامل معه على أنه تكلفة دورية معروفة ضمن أهداف مستوى الخدمة (⁨SLOs⁩)، لا كحادث. معدّل إعادة تشغيل أعلى من كل 100 عملية عرض يعني أن المستندات أثقل من المتوقَّع.

تنمو الذاكرة على مدى دُفعة طويلة

قسم بعنوان «تنمو الذاكرة على مدى دُفعة طويلة»

يقيّد BrowserPool النمو عبر إعادة التشغيل كل 100 عملية عرض، لكن العامل طويل العمر جداً قد يظل يراكم الذاكرة. استدعِ close() بين الدُّفعات الكبيرة لإعادة تدوير ⁨Chrome⁩ مبكراً، وشغّل العامل ضمن حد ذاكرة المضيف.

  1. أعِد إنتاج المشكلة بجزء ⁨HTML⁩ موثوق وبأقل حجم ممكن للفصل بين مشكلات الدخل ومشكلات البيئة.
  2. شغّل chromium --headless --dump-dom about:blank على المضيف بصلاحية مستخدم العامل.
  3. احقن مُسجِّلاً متوافقاً مع توصية معايير ⁨PHP⁩ رقم 3 (⁨PSR-3⁩) واقرأ سطري info/notice، بما يشمل مسار الملف الثنائي وعدد عمليات إعادة التشغيل.
  4. تأكّد من تثبيت chrome-php/chrome: لن يُطلق BrowserPool::getBrowser() الاستثناء ChromeNotAvailableException عندما يكون متاحاً.
  5. تحقّق من الاستثناء السابق للاستثناء لمعرفة سبب ⁨Chrome⁩ الكامن.
  • /integrations/artisan/install/
  • /integrations/artisan/configuration/
  • /integrations/artisan/security-and-operations/
  • /integrations/artisan/chrome-renderer-setup/
  • /integrations/artisan/production-usage/