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

الاستثناءات: تسلسل هرمي مُصنَّف

كل استثناء يرميه ⁨NextPDF⁩ يمتد من فئة أساس مجردة واحدة، NextPdfException، بحيث يمكنك معالجة أي خطأ في المحرك باستخدام catch واحد. ويطبّق كل استثناء نطاقي ContextAwareExceptionInterface ويكشف حقولاً تشخيصية مُهيكلة للتسجيل ومراقبة أداء التطبيقات (⁨APM⁩) دون تحليل سلسلة الرسالة.

Terminal window
composer require nextpdf/core:^3

يتألف التسلسل الهرمي من ثلاث طبقات:

RuntimeException (PHP SPL)
└── NextPdfException (abstract; implements ContextAwareExceptionInterface)
├── InvalidConfigException
├── FontNotFoundException
├── FontParsingException
├── ImageProcessingException
├── SignatureException
├── EncryptionException
├── WriterException
├── PageLayoutException
├── HtmlParsingException
├── CompressionException
├── NotImplementedException
├── … (23 domain exceptions total)
└── Strict\StrictModeViolation (abstract)
├── Strict\IncompatibleRenderingModeException
├── Strict\OracleConformanceFailure
└── Strict\UnregisteredCssDeviation

يمتد NextPdfException من RuntimeException في مكتبة ⁨PHP⁩ القياسية (⁨SPL⁩). عند التقاط RuntimeException، تلتقط أيضاً أخطاء ⁨NextPDF.⁩ وعند التقاط NextPdfException، تحصر المعالِج في أخطاء المحرك. التقط فئة طرفية عند الحاجة إلى تعافٍ موجَّه. تجمع شجرة Strict\ الفرعية انتهاكات وضع المطابقة تحت StrictModeViolation المجرد، وهو بدوره يمتد من NextPdfException.

السياق، لا الرموز النصية. يحدد ⁨NextPDF⁩ الخطأ عبر نوع ⁨PHP⁩ الخاص به، لا عبر رمز خطأ نصي. ولا تُعرّف فئات الاستثناء أي ثابت رمز NPDF-####. بدلاً من ذلك، يُرجِع ContextAwareExceptionInterface::getContext() مصفوفة array<string, mixed> من حقول أولية بصيغة ⁨snake_case⁩ آمنة للتسلسل داخل سجل أو حمولة ⁨APM.⁩ يُرجِع NextPdfException::getContext() القيمة [] افتراضياً. ويتجاوزه كل استثناء نطاقي بحقول خاصة بذلك الإخفاق. على سبيل المثال، يُرجِع FontNotFoundException::getContext() الحقول font_name وsearch_paths وfallback_attempted. ويُرجِع WriterException الحقلين output_path وwriter_state. ويُرجِع InvalidConfigException الحقول config_key وgiven_value وexpected_type. وتنتمي المعرّفات النصية المستقرة NEXTPDF_W_* إلى تعداد WarningCode غير القاتل في وحدة ⁨Support⁩، لا إلى الاستثناءات.

القابلية للإجراء. توضّح كتلة التوثيق (⁨docblock⁩) لفئة كل استثناء نطاقي مَن يمكنه التصرف بشأنه: المطوِّر، أو البنية التحتية، أو المستدعي للمكتبة. InvalidConfigException خطأ مطوِّر؛ صحّح التهيئة. FontNotFoundException خطأ مطوِّر أو بنية تحتية؛ تحقق من المسار أو أذونات الملف. WriterException خطأ بنية تحتية؛ افحص القرص أو الأذونات أو دفق المُخرَج. NotImplementedException خطأ مستدعٍ؛ أزِل الاستدعاء أو ثبّت على إصدار يُنجِز المتابعة المسماة. وتوفّر عدة استثناءات مُنشئات مسماة لتحديد الأسباب الجذرية بدقة، مثل SignatureException::ltvCapabilityMissing() و::tsaRequired() وما شابه. وبذلك يرى المشغّلون السبب الفعلي بدلاً من رسالة عامة.

سطح واجهة برمجة التطبيقات (⁨API⁩)

قسم بعنوان «سطح واجهة برمجة التطبيقات (⁨API⁩)»
الرمزالنوعالأعضاء الرئيسيون
NextPDF\Contracts\ContextAwareExceptionInterfaceواجهةgetContext(): array<string, mixed>
NextPDF\Exception\NextPdfExceptionفئة مجردةيمتد من RuntimeException؛ getContext() (افتراضياً [])
NextPDF\Exception\InvalidConfigException⁨final⁩getConfigKey(), getGivenValue(), getExpectedType(), getContext()
NextPDF\Exception\FontNotFoundException⁨final⁩getFontName(), getSearchPaths(), wasFallbackAttempted(), getContext()
NextPDF\Exception\SignatureException⁨final⁩getCertInfo(), getSignatureLevel(), getDetail(), getContext()؛ مُنشئات مسماة ltvCapabilityMissing(), tsaRequired(), httpClientMissing(), …
NextPDF\Exception\WriterException⁨final⁩getOutputPath(), getWriterState(), getContext()
NextPDF\Exception\PageLayoutException⁨final⁩getPageNumber(), getContext()
NextPDF\Exception\NotImplementedException⁨final⁩$feature, $followUp
NextPDF\Exception\Strict\StrictModeViolation⁨abstract⁩يمتد من NextPdfException
NextPDF\Exception\Strict\IncompatibleRenderingModeException⁨final⁩يمتد من StrictModeViolation

المجموعة الكاملة للفئات الطرفية (23): BarcodeEncoderNotFoundException, BarcodeException, CompressionException, ContentStreamBalanceException, CssParserLimitExceededException, CssResolutionBudgetExceededException, EncryptionException, FontNotFoundException, FontParsingException, GraphicsStateBalanceException, HtmlParsingException, ImageProcessingException, InvalidConfigException, LinearizationInvariantException, LinearizationUnimplementedException, MissingShadingResourceException, NotImplementedException, PageLayoutException, PdfRViolationException, SignatureException, TemplateException, UnsupportedAlgorithmException, WriterException.

التقط أي خطأ في المحرك عبر التقاط النوع الأساسي.

<?php
declare(strict_types=1);
use NextPDF\Core\Document;
use NextPDF\Exception\NextPdfException;
try {
$doc = Document::createStandalone();
$doc->addPage();
$doc->setFont('helvetica', '', 12);
$doc->cell(0, 10, 'Hello');
$doc->save('out.pdf');
} catch (NextPdfException $e) {
\error_log($e->getMessage());
}

يطبّق المثال القابل للتشغيل examples/15-exception-handling.php هذا النمط.

تعافَ على مستوى الفئة الطرفية، وأرسِل السياق المُهيكل إلى مسار التسجيل.

<?php
declare(strict_types=1);
use NextPDF\Contracts\ContextAwareExceptionInterface;
use NextPDF\Core\Document;
use NextPDF\Exception\FontNotFoundException;
use NextPDF\Exception\NextPdfException;
use Psr\Log\LoggerInterface;
function render(Document $doc, LoggerInterface $logger): void
{
try {
$doc->setFont('Brand-Sans', '', 12);
$doc->cell(0, 10, 'Invoice');
$doc->save('invoice.pdf');
} catch (FontNotFoundException $e) {
// Targeted recovery: fall back to a built-in font.
$logger->warning($e->getMessage(), $e->getContext());
$doc->setFont('helvetica', '', 12);
$doc->save('invoice.pdf');
} catch (NextPdfException $e) {
// Any other engine error: structured context, then rethrow.
$context = $e instanceof ContextAwareExceptionInterface
? $e->getContext()
: [];
$logger->error($e->getMessage(), $context);
throw $e;
}
}
  • ترتيب الالتقاط مهم. أدرِج الفئات الطرفية قبل NextPdfException؛ لأن وجود catch (NextPdfException) في المقدمة يبتلع كل فئة فرعية.
  • تستخدم مفاتيح getContext() صيغة ⁨snake_case⁩، وتكون القيم أوّلية أو قوائم من القيم الأوّلية، دون كائنات متداخلة. والحمولة آمنة للتسلسل بترميز تدوين كائنات جافاسكريبت (⁨JSON⁩).
  • يُرجِع NextPdfException::getContext() الأساسي []. والفئة الفرعية التي لا تتجاوزه لا تحمل أي حقول مُهيكلة. في هذه الحالة، اعتمِد على getMessage().
  • NextPdfException مجرد؛ لا يمكنك إنشاء مثيل منه مباشرةً. أطلِق فئة طرفية محددة.
  • NotImplementedException صريح بشكل متعمَّد. فهو يشير إلى تطبيق غائب عمداً، لا إلى إخفاق عابر. لا تعِد محاولته.
  • تشير انتهاكات Strict\* إلى خرق عقد وضع المطابقة، لا إلى خطأ وقت تشغيل قابل للتعافي. عامِلها كعيوب تهيئة أو إدخال.
  • لا يوجد ثابت رمز خطأ نصي. طابِق على نوع الاستثناء. ومرّر getContext() للمستهلكين الآليين.

ينشئ الاستثناء كائناً واحداً ويستدعي sprintf لبناء الرسالة: ⁨O⁩(1). ويُرجِع getContext() مصفوفة ترابطية صغيرة مبنية من حقول محفوظة مسبقاً: ⁨O⁩(1) في عدد الحقول. تعمل الاستثناءات على مسار الإخفاق، لا على المسار الساخن. والتكلفة لا تُذكر مقارنةً بالعمل الذي أخفق. وperformance_budget الافتراضية لهذه الصفحة المرجعية هي wall_ms: 1500 وpeak_mb: 64.

قد تحمل حقول السياق تفاصيل مشتقّة من المستند. يتضمّن FontNotFoundException مسارات البحث في نظام الملفات، ويتضمّن WriterException مسار المُخرَج، ويتضمّن InvalidConfigException القيمة المُمرَّرة. قبل تمرير السياق إلى مَصرِف تسجيل منخفض الثقة، نظّف الحقول أو مرّر قائمة سماح بالمفاتيح فقط، لأن المسارات والقيم قد تكشف بنية النشر أو إدخال المستخدم. ورسائل الاستثناءات مقروءة بشرياً وقد تتضمّن التفاصيل نفسها. لا تعرض الرسائل الخام للمستخدمين النهائيين في سياق حساس أمنياً. يربط SignatureException عمداً السبب الجذري المحدد، مثل حزمة مفقودة أو محدّد موقع موارد موحّد (⁨URL⁩) فارغ لسلطة ختم زمني (⁨TSA⁩)، بالرسالة كي يتمكّن المشغّلون من الفرز دون البحث في مواضع الاستدعاء. وهذا التفصيل موجَّه إلى المشغّل، لا إلى المستخدم النهائي.

تُعرّف هذه الوحدة نموذج أخطاء للمحرك ولا تتضمن أي استشهاد بمعيار معياري. أمّا الاستثناءات المُطلَقة لانتهاكات المعايير، مثل PdfRViolationException أو Strict\OracleConformanceFailure، فتشير إلى البند الحاكم لها في الوحدة التي تكتشف الانتهاك، لا هنا.

  • /modules/core/contracts/ — تعريف ContextAwareExceptionInterface
  • /modules/core/observability/ — تمرير getContext() إلى ⁨APM⁩
  • /modules/core/config/InvalidConfigException، NotImplementedException
  • /modules/core/support/DegradedException؛ WarningCode (NEXTPDF_W_*)
  • /modules/core/event/InvalidConfigException من addListener()

المسرد: الاستثناء المدرك للسياق · سياسة التدهور