渲染与 I/O 错误
这些条目涵盖在以下过程中抛出的渲染与输入/输出(I/O)异常: HTML 流水线对内容进行布局、分页媒体解析器分配页面几何、文本整形器处理复杂脚本、排版阶段进行断行、写入器序列化一个文档、读取器解析一个已有的 PDF,以及元数据阶段读取一个 Extensible Metadata Platform(XMP)数据包。
下文出现了两套基类层级,而二者的差异决定了你在一次 catch
之后能读取哪些诊断数据:
NextPdfException实现了ContextAwareExceptionInterface::getContext(): array。基类实现返回一个空数组;只有当子类重写getContext()时,它才携带结构化的键。那些不重写它的子类仍然通过public readonly属性暴露其数据。- 此处有几个类直接继承 PHP 的
RuntimeException。它们不是上下文感知的,也没有getContext()方法;请改为读取它们的getMessage()和任何公开属性。
每个条目都会指明确切的类、触发条件、它携带的上下文键或公开属性,以及恢复路径。
HTML 布局与分页媒体
标题为“HTML 布局与分页媒体”的章节UnsplittableContentException
标题为“UnsplittableContentException”的章节- When it is thrown. 当被标记为
break-inside: avoid的内容(一个其断行约束为Avoid的表格单元格)的测得高度超过单个页面的可用高度时,HTML 布局引擎会抛出它。引擎无法同时满足 avoid-break 约束和页面边界,因此它会失败,而非静默溢出。 - Carried data. 继承
NextPdfException,但不重写getContext(),因此getContext()返回一个空数组。诊断数据位于public readonly属性上:gridRow(int)、gridCol(int)、contentHeight(float,磅)和pageHeight(float,磅)。消息会指明单元格坐标和两个高度。 - Recovery. 移除出问题单元格上的
break-inside: avoid约束、 减少该单元格的内容以使它能容纳进一个页面,或增大页面尺寸或减小其边距,以使可用高度能容纳该内容。
BudgetExceededException
标题为“BudgetExceededException”的章节- When it is thrown. 当四个资源预算层级之一(定义于架构决策记录
ADR-020)被突破,且调用方选择了硬失败而非软回退时,retained 模式的布局原语会抛出它。默认路径不会抛出:
ContainerLayout::acceptChild()返回false,调用方回退到块布局,并发出一条警告。该异常保留给配置时的验证,以及给那些断言确切突破元组的测试。这些层级是per-child(一个被捕获的子流超出其上限)、per-container(Tier 1 的节点数量预算)、per-document(布局遍数或嵌套深度预算), 以及global(SDK 级别的 256 MB 峰值常驻集大小上限)。 - Carried data. 重写
getContext(),它返回一个被应用性能监控 (APM)工具消费的稳定八键形态:budgetTier、exceededValue、budgetLimit、containerType、phase、breachOrigin、captureSize和processedItemCount。前四个键是最初的 v1.0.0 子集,始终会被填充;后四个则在不带它们调用构造函数时默认为null或0。getCausalWarningCode()会把(层级、容器类型)元组映射到软回退路径本会发出的那个WarningCode。 - Recovery. 对于配置突破,把所请求的值降回已记录的范围内(例如,retained 节点预算通过
Config::withRetainedNodeBudget()接受5,000到100,000)。对于内容突破, 减少容器嵌套或节点数量,或依赖默认的软回退到块布局,而非选择那个硬失败表面。
UnsupportedNamedPageException
标题为“UnsupportedNamedPageException”的章节- When it is thrown. 当一个文档声明了一条具名的
@page <ident> { … }规则(通过page: <ident>属性绑定到内容)时,分页媒体阶段会失败即关闭地抛出它。来自 CSS Paged Media Level 3 §3.4 和 Level 4 §3.2 的具名页面——包括:first、:left、:right和:blank伪类以及具名的size:和rotate:覆盖——会被解析,但没有生产布局路径会消费它们。引擎会拒绝,而非发出丢弃该规则本会产生的那种静默错误的默认分页。 - Carried data. 重写
getContext(),它返回page_names(触发该失败的各个不同标识,按源代码顺序)、has_size_override(bool)、has_rotate_override(bool),以及has_pseudo_classes(bool)。同样的值也暴露在pageNames、hasSizeOverride、hasRotateOverride和hasPseudoClasses公开属性上。 - Recovery. 移除那些具名的
@page <ident>规则和任何page: <ident>绑定,并通过受支持的未具名@page { … }规则及其伪类形式来表达预期的几何。或者,固定到一个将落地完整具名页面布局支持的未来版本。
排版与文本整形
标题为“排版与文本整形”的章节IcuRequirementException
标题为“IcuRequirementException”的章节- When it is thrown. 当文本分段需要 International Components for
Unicode(ICU)断行迭代器,但 require-ICU 策略处于激活状态
(
NEXTPDF_REQUIRE_ICU=1),而ext-intl扩展和IntlBreakIterator不可用时,文本分段会抛出它。 - Carried data. 直接继承
RuntimeException,因此它不是上下文感知的,也没有getContext()。它是同一代码路径先前抛出的通用异常的一个严格细化,因此现有的catch (\RuntimeException)处理器会继续工作。 - Recovery. 安装并启用
ext-intl以使 ICU 断行迭代器可用,或在 require-ICU 策略并非强制的场合,取消设置NEXTPDF_REQUIRE_ICU以回退到非 ICU 的分段器。
ScriptShaperException
标题为“ScriptShaperException”的章节- When it is thrown. 这是脚本整形服务提供者接口 (SPI)的基异常。它今天不会被直接抛出;而是会抛出具体的子类型。捕获这个类型以在一处统一处理任何整形失败。
- Carried data. 直接继承
RuntimeException;不是上下文感知的,没有getContext()。 - Recovery. 在具体子类型上进行分支。关于当前版本中唯一提供的子类型,参见下文的
NotYetImplementedException。
NotYetImplementedException
标题为“NotYetImplementedException”的章节- When it is thrown. 对于那些具体整形被推迟的脚本(蒙古文和藏文),每个占位脚本整形器都会从其
shape()体中抛出它。 整形 SPI 接缝在架构上已就绪,但真正的整形仍待一个经母语者验证的夹具。抛出一个异常而非一个静默的空操作,会在运行时浮现意外的生产接线,而非把未整形的文本发出到一个宣称带标记无障碍的 PDF 中。 - Carried data. 继承
ScriptShaperException(因此也继承RuntimeException),所以它不是上下文感知的,也没有getContext()。 诊断数据位于它的public readonly属性上:bcp47LanguageTag(该运行的 BCP-47 标签,例如mn-Mong或bo-Tibt)和missingCapability(该实现所缺少的具体能力)。 消息会包含两者。 - Recovery. 不要在生产中把未实现脚本的运行经由整形器路由。在上游检测语言标签,并要么回退到一个不同的渲染路径,要么固定到一个将落地受影响脚本整形的未来版本。
写入器输出配置与加密
标题为“写入器输出配置与加密”的章节Pdf14FeatureRejectedException
标题为“Pdf14FeatureRejectedException”的章节- When it is thrown. 当一个文档包含一个在 PDF 1.4 输出配置文件(ISO 19005-1:2005 / PDF/A-1)下被禁止的特性时,写入器会抛出它,该配置文件禁止那些在更高 PDF 版本中引入的构造。
- Carried data. 继承
NextPdfException,但不重写getContext(),因此getContext()返回一个空数组。诊断数据位于它的public readonly属性上:feature(被拒绝的特性名称)、reason(它为何被禁止)和isoClause(ISO 条款引用)。 消息会组合这三者。 - Recovery. 移除被拒绝的特性,或用一个 PDF 1.4 兼容的等价物替换它,或瞄准一个允许该特性的更高输出配置文件。
Pdf20FeatureRejectedException
标题为“Pdf20FeatureRejectedException”的章节- When it is thrown. 当一个文档包含一个在严格 PDF 2.0 输出配置文件下被禁止的特性时,写入器会抛出它。ISO 32000-2:2020 弃用了 PDF 1.7 仍然允许的构造——最显著的是 Standard 14 Type 1 字体(§9.6.2),它们在一个一致的 PDF 2.0 文档中必须被嵌入。
- Carried data. 与
Pdf14FeatureRejectedException形态相同:继承NextPdfException,不重写getContext()(返回一个空数组), 并把feature、reason和isoClause暴露为public readonly属性。 - Recovery. 修复被拒绝的特性——例如,嵌入那 base 14
字体——或者在存在已记录逃生舱的地方采用它(对于非嵌入的
base 14 字体,
Document::allowNonEmbeddedBase14())。
PublicKeyEncryptionUnsupportedException
标题为“PublicKeyEncryptionUnsupportedException”的章节- When it is thrown. 当文档的
encryptionMode为pubkey(一个公钥接收者列表)时,PdfWriter::build()会在入口点抛出它,此时写入器端的公钥流体加密分派尚未接线。提前拒绝可以防止静默地发出一个调用方误以为已加密的未加密 PDF。 - Carried data. 直接继承
RuntimeException,因此它不是上下文感知的,也没有getContext()。它是同一站点先前抛出的通用异常的一个严格细化,因此现有的catch (\RuntimeException)处理器会继续工作。 - Recovery. 改用一个受支持的加密模式(基于密码的加密), 而非公钥接收者列表,或固定到一个将落地公钥加密支持的版本。当它被抛出时,不要把输出当作已加密来处理。
读取器与元数据输入
标题为“读取器与元数据输入”的章节UnsupportedPdfStructureException
标题为“UnsupportedPdfStructureException”的章节- When it is thrown. 当一个输入 PDF 落在其受支持的范围之外时,
对象图读取器会失败即关闭地抛出它。该读取器支持经典的交叉引用表(ISO 32000-2:2020 §7.5.4)、交叉引用流
(§7.5.8)、对象流压缩的对象(§7.5.7)、多修订版的
/Prev链(§7.5.6),以及经由/XRefStm的混合引用文件(§7.5.8.4)。 那个范围之外的任何内容都会浮现这个异常,而非一个部分或猜测的解析。具名构造函数映射到这些原因案例:encrypted()、damagedCrossReference()、cyclicReferenceChain()、nonConformantObjectStream()、irresolvableObjectCollision()、truncatedFile(),以及crossReferenceOffsetOutOfBounds()。 - Carried data. 直接继承
RuntimeException,因此它不是上下文感知的,也没有getContext()。它暴露一个public readonlyreason属性,其类型为UnsupportedPdfStructureReason(一个枚举),以便调用方在精确的类别上分支,而无需解析消息;一个可选的detail字符串和一个previousthrowable 可以添加有界的、不敏感的上下文。默认消息是该原因的不泄漏摘要。 - Recovery. 在
reason上分支。对于EncryptedDocument,在读取之前运行一个解密步骤,因为解密在读取器的范围之外。对于DamagedCrossReference、TruncatedFile或CrossReferenceOffsetOutOfBounds,把该文件当作格式错误或不完整来处理,并重新获取或修复该源。对于CyclicReferenceChain、NonConformantObjectStream或IrresolvableObjectCollision,该输入违反了结构模型,无法按原样读取。
PacketTooLargeException
标题为“PacketTooLargeException”的章节- When it is thrown. 当一个被嵌入的 XMP 数据包超出已配置的字节上限时,流式 XMP 元数据读取器会抛出它。它是一个针对实体扩展和二次方爆炸式输入的防御性守卫(一个 128 MB 峰值上限,针对吉字节规模的被嵌入 XMP)。
- Carried data. 继承
NextPdfException,但不重写getContext(),因此getContext()返回一个空数组。诊断数据位于它的public readonly属性上:byteCount(观测到的字节数) 和cap(已配置的上限,以字节为单位)。消息会报告两者。 - Recovery. 把这份超大的元数据当作恶意或格式错误来拒绝或跳过。如果一个合法的文档确实需要一个更大的数据包,请有意地提高已配置的上限,权衡那个守卫本就是为了防止的内存耗尽风险。
另请参阅
标题为“另请参阅”的章节- Error reference index
- Fonts and tagging troubleshooting — 用于
NotYetImplementedException、ScriptShaperException和IcuRequirementException症状。 - PDF/A and PDF/UA validation troubleshooting — 用于
Pdf14FeatureRejectedException和Pdf20FeatureRejectedException症状。 - Encryption and permissions troubleshooting — 用于
PublicKeyEncryptionUnsupportedException和读取器的EncryptedDocument原因。