Exception:型別化例外階層
NextPDF 拋出的每個例外都繼承同一個抽象基底類別 NextPdfException,因此只用一個 catch 就能處理任何引擎錯誤。每個領域例外都實作 ContextAwareExceptionInterface,並提供結構化診斷欄位,讓記錄與 APM 不必剖析訊息字串就能取用。
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\UnregisteredCssDeviationNextPdfException 繼承自 SPL 的 RuntimeException。攔截 RuntimeException 也會一併攔截 NextPDF 錯誤。攔截 NextPdfException 則會縮小到引擎錯誤。若要進行針對性復原,請攔截特定葉節點類別。Strict\ 子樹會將符合性模式(conformance-mode)的違規歸到抽象的 StrictModeViolation 之下,而後者本身也繼承自 NextPdfException。
用情境,而非字串代碼。 NextPDF 透過錯誤的 PHP 型別辨識錯誤,而不是使用字串錯誤代碼。例外類別裡並沒有 NPDF-#### 這類代碼常數。取而代之的是,ContextAwareExceptionInterface::getContext() 會回傳一個 array<string, mixed>,內含 snake_case 的原始型別欄位,可安全地序列化到記錄或 APM payload。NextPdfException::getContext() 預設回傳 []。每個領域例外都會覆寫它,填入與該失敗相關的欄位。舉例來說,FontNotFoundException::getContext() 會回傳 font_name、search_paths,以及 fallback_attempted。WriterException 會回傳 output_path 與 writer_state。InvalidConfigException 會回傳 config_key、given_value,以及 expected_type。另一組獨立且穩定的 NEXTPDF_W_* 字串識別碼,屬於 Support 模組中非致命的 WarningCode 列舉,並不屬於例外。
可採取的行動。 每個領域例外的類別說明文件都會註明哪一方能對它採取行動——開發者、基礎設施,或函式庫呼叫端。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 | 抽象 | 繼承 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,值為原始型別或原始型別清單——沒有巢狀物件——因此這份 payload 一律可安全轉成 JSON。- 基底類別的
NextPdfException::getContext()會回傳[]。未覆寫它的子類別不帶任何結構化欄位。此時請改用getMessage()。 NextPdfException是抽象類別——你無法直接將它實例化。請拋出一個具體的葉節點類別。NotImplementedException是刻意設計為醒目的訊號:它代表的是有意未實作的功能,而不是暫時性失敗。請勿重試它。Strict\*違規代表的是符合性模式(conformance-mode)的合約違反,而不是可復原的執行階段錯誤。請將它們視為組態或輸入上的缺陷來處理。- 沒有字串錯誤代碼常數。請使用例外型別進行比對。請將
getContext()轉送給機器端消費者。
建構例外只需要一次物件配置,以及一次用來建立訊息的 sprintf——複雜度為 O(1)。getContext() 會回傳由既有欄位組成的小型關聯陣列,相對於欄位數量也是 O(1)。例外屬於失敗路徑,而不是熱路徑。相較於失敗的那項工作,這點成本微不足道。本參考頁面預設的 performance_budget 為 wall_ms: 1500、peak_mb: 64。
安全性說明
標題為「安全性說明」的區段情境欄位可能包含來自文件的細節:FontNotFoundException 含有檔案系統的搜尋路徑、WriterException 含有輸出路徑、InvalidConfigException 含有所提供的值。在轉送到低信任的記錄輸出端之前,請先清除情境鍵,或改用允許清單,因為這些路徑與值可能洩漏部署組態或使用者輸入。例外訊息供人閱讀,可能包含相同細節——在涉及安全性的情境下,請勿把原始訊息直接呈現給終端使用者。SignatureException 會刻意把具體的根本原因(缺少套件、空的 TSA URL)寫入訊息,讓維運人員不必逐一搜尋呼叫位置就能分類處理。這些細節面向維運人員,而不是終端使用者。
符合性
標題為「符合性」的區段本模組描述引擎的錯誤模型,不含任何規範性標準引用。因標準違規而拋出的例外——例如 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()