ข้ามไปยังเนื้อหา

Exception: ลำดับชั้น exception แบบมีชนิด

exception ทั้งหมดที่ NextPDF โยนออกมาล้วนสืบทอดจากคลาสฐานแบบ abstract เพียงคลาสเดียวคือ NextPdfException คุณจึงจัดการข้อผิดพลาดของเอนจินใดๆได้ด้วย catch เพียงตัวเดียว exception ของแต่ละโดเมน implement 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 ของ Standard PHP Library (SPL) การ catch RuntimeException จึงครอบคลุมข้อผิดพลาดของ NextPDF ด้วย ส่วนการ catch NextPdfException จะจำกัดตัวจัดการให้แคบลงเฉพาะข้อผิดพลาดของเอนจิน ให้ catch คลาสปลายทาง (leaf) เมื่อต้องการกู้คืนแบบเจาะจง ซับทรี Strict\ จัดกลุ่มการละเมิดในโหมดความสอดคล้องไว้ภายใต้คลาส abstract StrictModeViolation ซึ่งสืบทอดจาก NextPdfException อีกทอดหนึ่ง

บริบท ไม่ใช่รหัสแบบสตริง NextPDF ระบุข้อผิดพลาดด้วยชนิด PHP ของข้อผิดพลาดนั้น ไม่ใช่ด้วยรหัสข้อผิดพลาดแบบสตริง คลาส exception ไม่ได้กำหนดค่าคงที่รหัส NPDF-#### ใดๆ แต่ ContextAwareExceptionInterface::getContext() จะคืนค่า array<string, mixed> ของฟิลด์พื้นฐานแบบ snake_case ที่ serialize ลงในเพย์โหลดของล็อกหรือ APM ได้อย่างปลอดภัย NextPdfException::getContext() คืนค่า [] โดยค่าเริ่มต้น exception ของแต่ละโดเมนจะ override เมธอดนี้ด้วยฟิลด์สำหรับความล้มเหลวนั้น เช่น FontNotFoundException::getContext() คืนค่า font_name search_paths และ fallback_attempted ส่วน WriterException คืนค่า output_path และ writer_state และ InvalidConfigException คืนค่า config_key given_value และ expected_type ตัวระบุแบบสตริง NEXTPDF_W_* ที่เสถียรเป็นของ enum WarningCode สำหรับคำเตือนที่ไม่ร้ายแรงในโมดูล Support ไม่ใช่ของ exception

ความสามารถในการดำเนินการ docblock ของคลาส exception แต่ละโดเมนระบุว่าใครควรดำเนินการกับข้อผิดพลาดนั้นได้: นักพัฒนา โครงสร้างพื้นฐาน หรือผู้เรียกใช้ไลบรารี InvalidConfigException เป็นข้อผิดพลาดของนักพัฒนา ให้แก้ไขการกำหนดค่า FontNotFoundException เป็นข้อผิดพลาดของนักพัฒนาหรือโครงสร้างพื้นฐาน ให้ตรวจสอบพาธหรือสิทธิ์ของไฟล์ WriterException เป็นข้อผิดพลาดของโครงสร้างพื้นฐาน ให้ตรวจสอบดิสก์ สิทธิ์ หรือสตรีมเอาต์พุต NotImplementedException เป็นข้อผิดพลาดของผู้เรียกใช้ ให้ลบการเรียกออกหรือตรึงไว้ที่รีลีสที่มีงานติดตามผลตามชื่อที่ระบุ exception หลายรายการมีคอนสตรักเตอร์แบบมีชื่อสำหรับสาเหตุรากที่แม่นยำ เช่น SignatureException::ltvCapabilityMissing() ::tsaRequired() และรายการอื่นๆที่คล้ายกัน ผู้ปฏิบัติงานจึงเห็นสาเหตุที่แท้จริงแทนข้อความทั่วไป

สัญลักษณ์ชนิดสมาชิกหลัก
NextPDF\Contracts\ContextAwareExceptionInterfaceinterfacegetContext(): array<string, mixed>
NextPDF\Exception\NextPdfExceptionabstract classสืบทอดจาก RuntimeException; getContext() (ค่าเริ่มต้น [])
NextPDF\Exception\InvalidConfigExceptionfinalgetConfigKey(), getGivenValue(), getExpectedType(), getContext()
NextPDF\Exception\FontNotFoundExceptionfinalgetFontName(), getSearchPaths(), wasFallbackAttempted(), getContext()
NextPDF\Exception\SignatureExceptionfinalgetCertInfo(), getSignatureLevel(), getDetail(), getContext(); named ctors ltvCapabilityMissing(), tsaRequired(), httpClientMissing(), …
NextPDF\Exception\WriterExceptionfinalgetOutputPath(), getWriterState(), getContext()
NextPDF\Exception\PageLayoutExceptionfinalgetPageNumber(), getContext()
NextPDF\Exception\NotImplementedExceptionfinal$feature, $followUp
NextPDF\Exception\Strict\StrictModeViolationabstractสืบทอดจาก NextPdfException
NextPDF\Exception\Strict\IncompatibleRenderingModeExceptionfinalสืบทอดจาก 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

catch ข้อผิดพลาดของเอนจินใดๆได้ด้วยการ catch ชนิดฐาน

<?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;
}
}
  • ลำดับของการ catch มีความสำคัญ ให้ระบุคลาสปลายทางก่อน NextPdfException เพราะ catch (NextPdfException) ที่อยู่ก่อนหน้าจะดักจับทุกคลาสย่อย
  • getContext() ใช้คีย์รูปแบบ snake_case และค่าต่างๆเป็นค่าพื้นฐานหรือลิสต์ของค่าพื้นฐาน โดยไม่มีอ็อบเจกต์ซ้อนกัน เพย์โหลดจึง serialize เป็น JavaScript Object Notation (JSON) ได้อย่างปลอดภัย
  • เมธอด NextPdfException::getContext() ของคลาสฐานคืนค่า [] คลาสย่อยที่ไม่ได้ override เมธอดนี้จะไม่มีฟิลด์ที่มีโครงสร้าง ในกรณีดังกล่าว ให้พึ่งพา getMessage() แทน
  • NextPdfException เป็นคลาส abstract จึงไม่สามารถสร้างอินสแตนซ์โดยตรงได้ ให้โยนคลาสปลายทางที่เป็นรูปธรรม
  • NotImplementedException ส่งสัญญาณอย่างชัดเจนโดยเจตนา เพื่อบ่งชี้ว่าจงใจไม่มีการนำไปใช้งาน ไม่ใช่ความล้มเหลวชั่วคราว อย่าลองทำซ้ำ
  • Strict\* คือการละเมิดที่บ่งชี้ว่ามีการฝ่าฝืนสัญญาในโหมดความสอดคล้อง ไม่ใช่ข้อผิดพลาดขณะรันที่กู้คืนได้ ให้ถือว่าเป็นข้อบกพร่องของการกำหนดค่าหรืออินพุต
  • ไม่มีค่าคงที่รหัสข้อผิดพลาดแบบสตริง ให้จับคู่ด้วยชนิดของ exception และส่งต่อ getContext() สำหรับผู้บริโภคที่เป็นเครื่องจักร

การสร้าง exception จะจัดสรรอ็อบเจกต์หนึ่งครั้งและเรียก sprintf เพื่อสร้างข้อความ: O(1) getContext() คืนค่าแอเรย์แบบ associative ขนาดเล็กที่สร้างจากฟิลด์ที่เก็บไว้อยู่แล้ว: O(1) ตามจำนวนฟิลด์ exception ทำงานบนเส้นทางความล้มเหลว ไม่ใช่เส้นทางที่ทำงานบ่อย (hot path) ต้นทุนนี้จึงน้อยมากเมื่อเทียบกับงานที่ล้มเหลว ค่า performance_budget เริ่มต้นสำหรับหน้าอ้างอิงนี้คือ wall_ms: 1500, peak_mb: 64

ฟิลด์บริบทอาจมีรายละเอียดที่มาจากเอกสารได้ FontNotFoundException มีพาธค้นหาในระบบไฟล์ WriterException มีพาธเอาต์พุต และ InvalidConfigException มีค่าที่ส่งเข้ามา ก่อนส่งต่อบริบทไปยังปลายทางบันทึกล็อกที่มีความเชื่อถือต่ำ ให้ล้างข้อมูลในฟิลด์หรือส่งเฉพาะคีย์ที่อยู่ในรายการอนุญาตเท่านั้น เพราะพาธและค่าต่างๆอาจเปิดเผยโครงสร้างการดีพลอยหรืออินพุตของผู้ใช้ ข้อความของ exception อ่านได้โดยมนุษย์และอาจมีรายละเอียดเดียวกัน อย่าแสดงข้อความดิบแก่ผู้ใช้ปลายทางในบริบทที่อ่อนไหวด้านความปลอดภัย SignatureException ผูกสาเหตุรากที่เป็นรูปธรรมไว้กับข้อความโดยเจตนา เช่น แพ็กเกจที่ขาดหายไปหรือ Uniform Resource Locator (URL) ที่ว่างเปล่าสำหรับ Time Stamping Authority (TSA) เพื่อให้ผู้ปฏิบัติงานคัดแยกปัญหาได้โดยไม่ต้องค้นหาตำแหน่งการเรียก รายละเอียดนั้นมีไว้สำหรับผู้ปฏิบัติงาน ไม่ใช่ผู้ใช้ปลายทาง

โมดูลนี้กำหนดแบบจำลองข้อผิดพลาดของเอนจินและไม่มีการอ้างอิงมาตรฐานเชิงบังคับ exception ที่ถูกโยนขึ้นเนื่องจากการละเมิดมาตรฐาน เช่น 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()

อภิธานศัพท์: exception ที่รับรู้บริบท · นโยบายการลดทอนการทำงาน