Lewati ke konten

Exception: hierarki exception bertipe

Setiap exception yang dilempar oleh NextPDF memperluas kelas dasar abstrak, NextPdfException, sehingga Anda dapat menangani error mesin apa pun dengan satu catch. Setiap exception domain mengimplementasikan ContextAwareExceptionInterface dan menyediakan kolom diagnostik terstruktur untuk pencatatan log dan pemantauan kinerja aplikasi (APM) tanpa perlu mengurai string pesan.

Terminal window
composer require nextpdf/core:^3

Hierarki ini terdiri dari tiga lapisan:

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 memperluas RuntimeException dari pustaka standar PHP (SPL). Menangkap RuntimeException juga akan menangkap error NextPDF. Menangkap NextPdfException mempersempit penanganan ke error mesin. Tangkap kelas daun untuk pemulihan yang terarah. Sub-pohon Strict\ mengelompokkan pelanggaran mode konformansi di bawah StrictModeViolation abstrak, yang juga memperluas NextPdfException.

Konteks, bukan kode string. NextPDF mengidentifikasi error berdasarkan tipe PHP-nya, bukan berdasarkan kode error string. Kelas-kelas exception tidak mendefinisikan konstanta kode NPDF-####. Sebagai gantinya, ContextAwareExceptionInterface::getContext() mengembalikan array<string, mixed> berisi kolom primitif snake_case yang aman untuk diserialisasi ke dalam payload log atau APM. NextPdfException::getContext() mengembalikan [] secara baku. Setiap exception domain menimpanya dengan kolom untuk kegagalan tersebut. Misalnya, FontNotFoundException::getContext() mengembalikan font_name, search_paths, dan fallback_attempted. WriterException mengembalikan output_path dan writer_state. InvalidConfigException mengembalikan config_key, given_value, dan expected_type. Pengenal string NEXTPDF_W_* yang stabil dimiliki oleh enum WarningCode non-fatal di modul Support, bukan oleh exception.

Dapat ditindaklanjuti. Docblock kelas pada setiap exception domain menyatakan siapa yang dapat menanganinya: pengembang, infrastruktur, atau pemanggil pustaka. InvalidConfigException adalah error pengembang; perbaiki konfigurasinya. FontNotFoundException adalah error pengembang atau infrastruktur; verifikasi path atau izin berkas. WriterException adalah error infrastruktur; periksa disk, izin, atau stream keluaran. NotImplementedException adalah error pemanggil; hapus pemanggilan tersebut atau pin ke rilis yang menyertakan tindak lanjut yang disebutkan. Beberapa exception menyediakan konstruktor bernama untuk akar penyebab yang presisi: SignatureException::ltvCapabilityMissing(), ::tsaRequired(), dan serupa. Operator melihat akar penyebab sebenarnya, bukan sekadar pesan generik.

SimbolJenisAnggota utama
NextPDF\Contracts\ContextAwareExceptionInterfaceinterfacegetContext(): array<string, mixed>
NextPDF\Exception\NextPdfExceptionkelas abstrakmemperluas RuntimeException; getContext() (baku [])
NextPDF\Exception\InvalidConfigExceptionfinalgetConfigKey(), getGivenValue(), getExpectedType(), getContext()
NextPDF\Exception\FontNotFoundExceptionfinalgetFontName(), getSearchPaths(), wasFallbackAttempted(), getContext()
NextPDF\Exception\SignatureExceptionfinalgetCertInfo(), getSignatureLevel(), getDetail(), getContext(); named ctors ltvCapabilityMissing(), tsaRequired(), httpClientMissing(), …
NextPDF\Exception\WriterExceptionfinalgetOutputPath(), getWriterState(), getContext()
NextPDF\Exception\PageLayoutExceptionfinalgetPageNumber(), getContext()
NextPDF\Exception\NotImplementedExceptionfinal$feature, $followUp
NextPDF\Exception\Strict\StrictModeViolationabstrakmemperluas NextPdfException
NextPDF\Exception\Strict\IncompatibleRenderingModeExceptionfinalmemperluas StrictModeViolation

Kumpulan kelas daun lengkap (23): BarcodeEncoderNotFoundException, BarcodeException, CompressionException, ContentStreamBalanceException, CssParserLimitExceededException, CssResolutionBudgetExceededException, EncryptionException, FontNotFoundException, FontParsingException, GraphicsStateBalanceException, HtmlParsingException, ImageProcessingException, InvalidConfigException, LinearizationInvariantException, LinearizationUnimplementedException, MissingShadingResourceException, NotImplementedException, PageLayoutException, PdfRViolationException, SignatureException, TemplateException, UnsupportedAlgorithmException, WriterException.

Tangkap error mesin apa pun dengan menangkap tipe dasar.

<?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());
}

Contoh yang dapat dijalankan examples/15-exception-handling.php menunjukkan pola ini.

Lakukan pemulihan di level daun, lalu kirim konteks terstruktur ke pipeline log.

<?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;
}
}
  • Urutan catch penting. Daftarkan kelas daun sebelum NextPdfException; catch (NextPdfException) yang diletakkan lebih awal akan menelan setiap subkelas.
  • getContext() menggunakan kunci snake_case, dan nilainya berupa primitif atau daftar primitif, tanpa objek bersarang. Payload tersebut aman untuk serialisasi JavaScript Object Notation (JSON).
  • Implementasi dasar NextPdfException::getContext() mengembalikan []. Subkelas yang tidak menimpanya tidak membawa kolom terstruktur. Dalam kasus itu, andalkan getMessage().
  • NextPdfException bersifat abstrak; Anda tidak dapat menginstansiasinya secara langsung. Lempar kelas daun konkret.
  • NotImplementedException sengaja dibuat eksplisit. Ini menandakan implementasi yang memang sengaja tidak tersedia, bukan kegagalan sementara. Jangan mencoba ulang.
  • Strict\* menandai pelanggaran kontrak mode konformansi, bukan error runtime yang dapat dipulihkan. Perlakukan sebagai cacat konfigurasi atau masukan.
  • Tidak ada konstanta kode error berbentuk string. Cocokkan berdasarkan tipe exception. Teruskan getContext() untuk konsumen mesin.

Membuat exception membutuhkan satu alokasi objek ditambah pemanggilan sprintf untuk membangun pesan: O(1). getContext() mengembalikan array asosiatif kecil yang dibangun dari kolom yang sudah ada: O(1) terhadap jumlah kolom. Exception berjalan pada jalur kegagalan, bukan jalur panas. Biayanya dapat diabaikan dibandingkan pekerjaan yang gagal. Nilai performance_budget baku untuk halaman referensi ini adalah wall_ms: 1500, peak_mb: 64.

Kolom konteks dapat membawa detail yang berasal dari dokumen. FontNotFoundException menyertakan path pencarian filesystem, WriterException menyertakan path keluaran, dan InvalidConfigException menyertakan nilai yang diberikan. Sebelum meneruskan konteks ke sink log dengan tingkat kepercayaan rendah, bersihkan kolom atau hanya teruskan kunci yang masuk daftar izin, karena path dan nilai dapat mengungkap tata letak penyebaran atau masukan pengguna. Pesan exception dapat dibaca manusia dan mungkin menyertakan detail yang sama. Jangan tampilkan pesan mentah kepada pengguna akhir dalam konteks yang sensitif terhadap keamanan. SignatureException sengaja memasukkan akar penyebab konkret, seperti paket yang hilang atau Uniform Resource Locator (URL) kosong untuk Time Stamping Authority (TSA), ke dalam pesan sehingga operator dapat melakukan triase tanpa menelusuri lokasi pemanggilan. Detail tersebut ditujukan kepada operator, bukan kepada pengguna akhir.

Modul ini mendefinisikan model error mesin dan tidak memuat kutipan standar normatif. Exception yang dilempar untuk pelanggaran standar, misalnya PdfRViolationException atau Strict\OracleConformanceFailure, merujuk klausa yang mengaturnya di modul yang mendeteksi pelanggaran, bukan di sini.

  • /modules/core/contracts/ContextAwareExceptionInterface (definisi antarmuka)
  • /modules/core/observability/ — meneruskan getContext() ke APM
  • /modules/core/config/InvalidConfigException, NotImplementedException
  • /modules/core/support/DegradedException; WarningCode (NEXTPDF_W_*)
  • /modules/core/event/InvalidConfigException dari addListener()

Glosarium: context-aware exception · degradation policy