コンテンツにスキップ

Exception: 型付き例外階層

NextPDF がスローするすべての例外は、単一の抽象基底クラス NextPdfException を継承しているため、単一の catch であらゆるエンジンエラーを処理できます。各ドメイン例外は ContextAwareExceptionInterface を実装しており、メッセージ文字列を解析しなくても、ロギングや APM 向けの構造化された診断フィールドを公開します。

Terminal window
composer require nextpdf/core:^3

この階層は 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 は SPL の RuntimeException を継承します。RuntimeException を捕捉すると、NextPDF のエラーも捕捉されます。NextPdfException を捕捉すると、エンジンエラーだけに絞り込めます。対象を絞って復旧する場合は、リーフクラスを捕捉します。Strict\ サブツリーは、コンフォーマンスモード違反を抽象クラス StrictModeViolation の下にまとめます。この抽象クラス自体も NextPdfException を継承しています。

文字列コードではなくコンテキスト。 NextPDF は、文字列のエラーコードではなく PHP 型でエラーを識別します。例外クラスには NPDF-#### のようなコード定数はありません。代わりに、ContextAwareExceptionInterface::getContext() は、ログや APM のペイロードへ安全にシリアライズできる snake_case のプリミティブフィールドで構成された array<string, mixed> を返します。NextPdfException::getContext() はデフォルトで [] を返します。各ドメイン例外は、その障害に関連するフィールドを返すようにこれをオーバーライドします。たとえば、FontNotFoundException::getContext()font_namesearch_pathsfallback_attempted を返します。WriterExceptionoutput_pathwriter_state を返します。InvalidConfigExceptionconfig_keygiven_valueexpected_type を返します。独立して安定した NEXTPDF_W_* 文字列識別子は、例外ではなく、Support モジュール内の非致命的な WarningCode 列挙型に属します。

対処可能性。 各ドメイン例外のクラス docblock には、誰が対処できるか(開発者、インフラ、ライブラリの呼び出し元)が記載されています。InvalidConfigException は開発者のエラーです(設定を修正してください)。FontNotFoundException は開発者またはインフラのエラーです(パスまたはファイル権限を確認してください)。WriterException はインフラのエラーです(ディスク、権限、出力ストリーム)。NotImplementedException は呼び出し元のエラーです(その呼び出しを削除するか、指定されたフォローアップが導入されるリリースに固定してください)。いくつかの例外には、正確な根本原因を示す名前付きコンストラクター(SignatureException::ltvCapabilityMissing()::tsaRequired() など)があります。これにより、運用担当者は汎用的なメッセージではなく、実際の原因を確認できます。

シンボル種別主なメンバー
NextPDF\Contracts\ContextAwareExceptionInterfaceinterfacegetContext(): array<string, mixed>
NextPDF\Exception\NextPdfExceptionabstract class継承元: RuntimeExceptiongetContext()(デフォルトは []
NextPDF\Exception\InvalidConfigExceptionfinalgetConfigKey(), getGivenValue(), getExpectedType(), getContext()
NextPDF\Exception\FontNotFoundExceptionfinalgetFontName(), getSearchPaths(), wasFallbackAttempted(), getContext()
NextPDF\Exception\SignatureExceptionfinalgetCertInfo(), getSignatureLevel(), getDetail(), getContext(); 名前付きコンストラクター 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

基底型であらゆるエンジンエラーを捕捉します。

<?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 で、値はプリミティブまたはプリミティブのリストです(ネストしたオブジェクトはありません)。そのため、ペイロードは常に JSON セーフです。
  • 基底クラスの NextPdfException::getContext()[] を返します。これをオーバーライドしないサブクラスは、構造化されたフィールドを持ちません。その場合は getMessage() を利用してください。
  • NextPdfException は抽象クラスであり、直接インスタンス化することはできません。具象のリーフクラスをスローしてください。
  • NotImplementedException は意図的に目立つように設計されています。これは一時的な障害ではなく、意図的に存在しない実装を示します。これを再試行しないでください。
  • Strict\* の違反は、回復可能なランタイムエラーではなく、コンフォーマンスモードのコントラクト違反を示します。これらは設定または入力の不備として扱ってください。
  • 文字列のエラーコード定数はありません。例外の型でマッチングしてください。機械処理を行う利用者には getContext() を転送してください。

例外の生成は、単一のオブジェクト割り当てと、メッセージを構築する sprintf だけで完了し、O(1) です。getContext() は、すでに保持しているフィールドから小さな連想配列を構築して返し、フィールド数に対して O(1) です。例外はホットパスではなく、障害時のパスです。そのコストは、失敗した処理に比べれば無視できるほど小さいものです。このリファレンスページのデフォルトの performance_budgetwall_ms: 1500peak_mb: 64 です。

コンテキストフィールドには、ドキュメント由来の詳細が含まれることがあります。FontNotFoundException にはファイルシステムの検索パスが、WriterException には出力パスが、InvalidConfigException には指定された値が含まれます。パスや値はデプロイ構成やユーザー入力を明らかにする可能性があるため、信頼できないログシンクへ転送する前に、コンテキストキーをスクラブするか、許可リストで絞り込んでください。例外メッセージは人が読める形式で、同じ詳細を含む場合があります。セキュリティ上重要なコンテキストでは、生のメッセージをエンドユーザーに表示しないでください。SignatureException は、具体的な根本原因(パッケージの欠落、空の TSA URL)を意図的にメッセージへ結び付けます。これにより、運用担当者は呼び出し箇所を grep しなくてもトリアージできます。この詳細はエンドユーザー向けではなく、運用担当者向けです。

このモジュールはエンジンのエラーモデルであり、規範的な標準の引用は含みません。標準違反に対してスローされる例外(たとえば PdfRViolationExceptionStrict\OracleConformanceFailure)は、このページではなく、その違反を検出するモジュール側で、それぞれの準拠条項を参照します。

  • /modules/core/contracts/ContextAwareExceptionInterface の定義
  • /modules/core/observability/getContext() を APM に転送する
  • /modules/core/config/InvalidConfigException, NotImplementedException
  • /modules/core/support/DegradedException; WarningCodeNEXTPDF_W_*
  • /modules/core/event/InvalidConfigException、発生元は addListener()

用語集: コンテキスト対応例外 · デグラデーションポリシー