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()