Перейти к содержимому
getnextpdf.com

Ошибки рендеринга и ввода-вывода

Эти записи охватывают исключения рендеринга и ввода-вывода (I/O), генерируемые, пока конвейер HTML компонует содержимое, резолвер постраничного вывода назначает геометрию страницы, формирователь текста обрабатывает сложные письменности, типографский этап переносит строки, писатель сериализует документ, читатель разбирает существующий PDF, а этап метаданных читает пакет Extensible Metadata Platform (XMP).

Ниже появляются две базовые иерархии, и различие управляет тем, какие диагностические данные вы можете прочитать после catch:

  • NextPdfException реализует ContextAwareExceptionInterface::getContext(): array. Базовая реализация возвращает пустой массив; подкласс несёт структурированные ключи, только когда он переопределяет getContext(). Подклассы, которые не переопределяют его, всё равно раскрывают свои данные через свойства public readonly.
  • Несколько классов здесь наследуются напрямую от PHP-класса RuntimeException. Они не являются контекстно-зависимыми и не имеют метода getContext(); читайте вместо этого их getMessage() и любые публичные свойства.

Каждая запись называет точный класс, условие срабатывания, ключи контекста или публичные свойства, которые он несёт, и путь восстановления.

  • Когда генерируется. Движок компоновки HTML генерирует это, когда содержимое, помеченное break-inside: avoid (ячейка таблицы, чьё ограничение разрыва — Avoid), имеет измеренную высоту, превышающую полезную высоту одной страницы. Движок не может удовлетворить и ограничение avoid-break, и границу страницы, поэтому он завершается сбоем, а не молча допускает переполнение.
  • Несомые данные. Наследуется от NextPdfException, но не переопределяет getContext(), поэтому getContext() возвращает пустой массив. Диагностические данные находятся в свойствах public readonly: gridRow (int), gridCol (int), contentHeight (float, пункты) и pageHeight (float, пункты). Сообщение называет координаты ячейки и обе высоты.
  • Восстановление. Уберите ограничение break-inside: avoid на проблемной ячейке, уменьшите содержимое ячейки, чтобы оно умещалось на одной странице, или увеличьте размер страницы либо уменьшите её поля, чтобы полезная высота вмещала содержимое.
  • Когда генерируется. Примитивы компоновки удерживаемого режима генерируют это, когда один из четырёх уровней бюджета ресурсов, определённых в записи архитектурного решения ADR-020, нарушен, а вызывающая сторона выбрала жёсткий сбой вместо мягкого запасного варианта. Путь по умолчанию не генерирует исключение: ContainerLayout::acceptChild() возвращает false, вызывающая сторона откатывается к блочной компоновке, и выдаётся предупреждение. Исключение зарезервировано для проверки во время конфигурации и для тестов, которые утверждают точный кортеж нарушения. Уровни — это per-child ( захваченный поток дочернего элемента превышает свой предел), per-container (бюджет количества узлов Tier 1), per-document (бюджет прохода компоновки или глубины вложенности) и global (потолок пикового resident-set-size в 256 МБ для всего SDK).
  • Несомые данные. Переопределяет getContext(), который возвращает стабильную форму из восьми ключей, потребляемую инструментами мониторинга производительности приложений (APM): budgetTier, exceededValue, budgetLimit, containerType, phase, breachOrigin, captureSize и processedItemCount. Первые четыре ключа являются исходным подмножеством v1.0.0 и всегда заполнены; последние четыре по умолчанию равны null или 0, когда конструктор вызван без них. getCausalWarningCode() сопоставляет кортеж (уровень, тип контейнера) с WarningCode, который выдал бы путь мягкого запасного варианта.
  • Восстановление. Для нарушения конфигурации верните запрошенное значение обратно в задокументированный диапазон (например, бюджет удерживаемых узлов принимает 5 000–100 000 через Config::withRetainedNodeBudget()). Для нарушения содержимого уменьшите вложенность контейнеров или количество узлов или положитесь на мягкий запасной вариант по умолчанию с переходом к блочной компоновке вместо выбора поверхности жёсткого сбоя.
  • Когда генерируется. Этап постраничного вывода генерирует это, с завершением при отказе, когда документ объявляет именованное правило @page <ident> { … } (привязанное к содержимому через свойство page: <ident>). Именованные страницы из CSS Paged Media Level 3 §3.4 и Level 4 §3.2 — включая псевдоклассы :first, :left, :right и :blank и именованные переопределения size: и rotate: — разбираются, но ни один продакшен-путь компоновки их не потребляет. Движок отказывает, а не выдаёт молча неверную пагинацию по умолчанию, к которой привело бы отбрасывание правила.
  • Несомые данные. Переопределяет getContext(), который возвращает page_names (список различных идентификаторов, вызвавших сбой, в порядке исходного кода), has_size_override (bool), has_rotate_override (bool) и has_pseudo_classes (bool). Те же значения раскрыты в публичных свойствах pageNames, hasSizeOverride, hasRotateOverride и hasPseudoClasses.
  • Восстановление. Уберите именованные правила @page <ident> и любые привязки page: <ident> и выразите задуманную геометрию через поддерживаемое неименованное правило @page { … } и его формы псевдоклассов. Либо закрепитесь на будущем релизе, в котором появится полная поддержка компоновки именованных страниц.
  • Когда генерируется. Сегментация текста генерирует это, когда ей нужен итератор переноса строк International Components for Unicode (ICU), но политика require-ICU активна (NEXTPDF_REQUIRE_ICU=1), при этом расширение ext-intl и IntlBreakIterator недоступны.
  • Несомые данные. Наследуется напрямую от RuntimeException, поэтому он не является контекстно-зависимым и не имеет getContext(). Это строгое уточнение обобщённого исключения, которое тот же путь кода ранее генерировал, поэтому существующие обработчики catch (\RuntimeException) продолжают работать.
  • Восстановление. Установите и включите ext-intl, чтобы итератор переноса ICU был доступен, или сбросьте NEXTPDF_REQUIRE_ICU, чтобы откатиться к не-ICU сегментатору там, где политика require-ICU не обязательна.
  • Когда генерируется. Это базовое исключение для интерфейса поставщика услуг формирования письменности (SPI). Сегодня оно не генерируется напрямую; вместо него генерируются конкретные подтипы. Перехватывайте этот тип, чтобы обработать любой сбой формирования в одном месте.
  • Несомые данные. Наследуется напрямую от RuntimeException; не контекстно-зависимо, нет getContext().
  • Восстановление. Ветвитесь по конкретному подтипу. См. NotYetImplementedException ниже — единственный подтип, поставляемый в текущем релизе.
  • Когда генерируется. Каждый формирователь-заглушка письменности генерирует это из своего тела shape() для письменностей, чьё конкретное формирование отложено (монгольская и тибетская). Шов SPI формирования архитектурно готов, но реальное формирование ожидает фикстуру, проверенную носителем языка. Генерация исключения вместо молчаливого отсутствия операции выявляет случайное продакшен-подключение во время выполнения, вместо того чтобы выдавать несформированный текст в PDF, который заявляет тегированную доступность.
  • Несомые данные. Наследуется от ScriptShaperException (и, следовательно, RuntimeException), поэтому он не является контекстно-зависимым и не имеет getContext(). Диагностические данные находятся в его свойствах public readonly: bcp47LanguageTag (тег BCP-47 прогона, такой как mn-Mong или bo-Tibt) и missingCapability (конкретная возможность, которой не хватает реализации). Сообщение включает обе.
  • Восстановление. Не направляйте прогоны в нереализованных письменностях через формирователь в продакшене. Определяйте языковой тег выше по потоку и либо откатывайтесь к другому пути рендеринга, либо закрепляйтесь на будущем релизе, в котором появится формирование для затронутой письменности.
  • Когда генерируется. Писатель генерирует это, когда документ содержит возможность, запрещённую под профилем вывода PDF 1.4 (ISO 19005-1:2005 / PDF/A-1), который запрещает конструкции, введённые в более поздних версиях PDF.
  • Несомые данные. Наследуется от NextPdfException, но не переопределяет getContext(), поэтому getContext() возвращает пустой массив. Диагностические данные находятся в его свойствах public readonly: feature (имя отклонённой возможности), reason (почему она запрещена) и isoClause (ссылка на пункт ISO). Сообщение объединяет все три.
  • Восстановление. Уберите или замените отклонённую возможность совместимым с PDF 1.4 эквивалентом или нацельтесь на более высокий профиль вывода, разрешающий эту возможность.
  • Когда генерируется. Писатель генерирует это, когда документ содержит возможность, запрещённую под строгим профилем вывода PDF 2.0. ISO 32000-2:2020 объявляет устаревшими конструкции, которые PDF 1.7 ещё разрешал — в первую очередь шрифты Standard 14 Type 1 (§9.6.2), которые должны быть внедрены в соответствующий документ PDF 2.0.
  • Несомые данные. Та же форма, что и у Pdf14FeatureRejectedException: наследуется от NextPdfException, не переопределяет getContext() (возвращает пустой массив) и раскрывает feature, reason и isoClause как свойства public readonly.
  • Восстановление. Устраните отклонённую возможность — например, внедрите базовые 14 шрифтов — или воспользуйтесь задокументированной лазейкой там, где она есть (для невнедрённых базовых 14 шрифтов — Document::allowNonEmbeddedBase14()).
  • Когда генерируется. PdfWriter::build() генерирует это в точке входа, когда encryptionMode документа равен pubkey (список получателей с открытым ключом), прежде чем диспетчеризация шифрования тела потока с открытым ключом на стороне писателя подключена. Отказ заранее предотвращает молчаливый выпуск незашифрованного PDF, который вызывающая сторона считала зашифрованным.
  • Несомые данные. Наследуется напрямую от RuntimeException, поэтому он не является контекстно-зависимым и не имеет getContext(). Это строгое уточнение обобщённого исключения, которое тот же участок ранее генерировал, поэтому существующие обработчики catch (\RuntimeException) продолжают работать.
  • Восстановление. Используйте вместо этого поддерживаемый режим шифрования (шифрование на основе пароля), а не список получателей с открытым ключом, или закрепитесь на релизе, в котором появится поддержка шифрования с открытым ключом. Не считайте вывод зашифрованным, когда это генерируется.
  • Когда генерируется. Читатель графа объектов генерирует это, с завершением при отказе, когда входной 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().
  • Несомые данные. Наследуется напрямую от RuntimeException, поэтому он не является контекстно-зависимым и не имеет getContext(). Он раскрывает свойство public readonly reason типа UnsupportedPdfStructureReason (перечисление), чтобы вызывающие стороны ветвились по точной категории без разбора сообщения; необязательная строка detail и previous-throwable могут добавить ограниченный, нечувствительный контекст. Сообщение по умолчанию — нераскрывающая сводка причины.
  • Восстановление. Ветвитесь по reason. Для EncryptedDocument выполните шаг расшифровки перед чтением, поскольку расшифровка вне области действия читателя. Для DamagedCrossReference, TruncatedFile или CrossReferenceOffsetOutOfBounds считайте файл некорректным или неполным и повторно получите либо восстановите источник. Для CyclicReferenceChain, NonConformantObjectStream или IrresolvableObjectCollision ввод нарушает структурную модель и не может быть прочитан как есть.
  • Когда генерируется. Потоковый читатель метаданных XMP генерирует это, когда встроенный пакет XMP превышает настроенный байтовый потолок. Это защитная мера против входных данных в стиле раскрытия сущностей и квадратичного взрыва (потолок пика 128 МБ против встроенного XMP гигабайтного масштаба).
  • Несомые данные. Наследуется от NextPdfException, но не переопределяет getContext(), поэтому getContext() возвращает пустой массив. Диагностические данные находятся в его свойствах public readonly: byteCount (наблюдаемое число байтов) и cap (настроенный предел в байтах). Сообщение сообщает оба.
  • Восстановление. Отклоните или пропустите слишком большие метаданные как вредоносные или некорректные. Если законному документу действительно нужен больший пакет, повысьте настроенный предел осознанно, взвесив риск исчерпания памяти, ради предотвращения которого мера существует.