استكشاف أخطاء Artisan وإصلاحها
لمحة سريعة
قسم بعنوان «لمحة سريعة»يظهر كل فشل في الجسر على هيئة استثناء مُصنَّف. طابِق الاستثناء والرسالة مع الجدول أدناه. يشير كل صف إلى فحص المصدر الذي أطلقه، حتى تتمكن من معالجة السبب لا العَرَض.
التشخيص حسب الاستثناء
قسم بعنوان «التشخيص حسب الاستثناء»ChromeNotAvailableException
قسم بعنوان «ChromeNotAvailableException»
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 المناسبة لتوزيعتك.
ChromeRenderException — مُخرَج فارغ
قسم بعنوان «ChromeRenderException — مُخرَج فارغ»
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، لذلك تكون سريعة ومنخفضة التكلفة عند تغطيتها بالاختبارات.
PdfParseException
قسم بعنوان «PdfParseException»
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 مبكراً، وشغّل العامل ضمن حد ذاكرة المضيف.
قائمة التحقّق التشخيصية
قسم بعنوان «قائمة التحقّق التشخيصية»- أعِد إنتاج المشكلة بجزء HTML موثوق وبأقل حجم ممكن للفصل بين مشكلات الدخل ومشكلات البيئة.
- شغّل
chromium --headless --dump-dom about:blankعلى المضيف بصلاحية مستخدم العامل. - احقن مُسجِّلاً متوافقاً مع توصية معايير PHP رقم 3 (PSR-3) واقرأ سطري
info/notice، بما يشمل مسار الملف الثنائي وعدد عمليات إعادة التشغيل. - تأكّد من تثبيت
chrome-php/chrome: لن يُطلقBrowserPool::getBrowser()الاستثناءChromeNotAvailableExceptionعندما يكون متاحاً. - تحقّق من الاستثناء السابق للاستثناء لمعرفة سبب Chrome الكامن.
انظر أيضاً
قسم بعنوان «انظر أيضاً»- /integrations/artisan/install/
- /integrations/artisan/configuration/
- /integrations/artisan/security-and-operations/
- /integrations/artisan/chrome-renderer-setup/
- /integrations/artisan/production-usage/