NextPDF istisna hiyerarşisiyle hataları ele alın
Bir bakışta
“Bir bakışta” başlıklı bölümNextPDF, istisnai durumlar için türlendirilmiş istisnalar fırlatır. Bir hatayı asla false veya null dönüş değerlerinin arkasına gizlemez. Her etki alanı istisnası, aynı soyut temel sınıf olan NextPdfException sınıfından türemiştir ve yapılandırılmış tanılama bağlamını ContextAwareExceptionInterface aracılığıyla sunar. Bu tarif, yakalamayı nerede yapacağınızı ve yapılandırılmış bağlamı bir uygulama performansı izleme (APM) işlem hattı için nasıl günlüğe kaydedeceğinizi gösterir. Ayrıca tek bir catch-all bloğunun hangi başarısızlıkları kapsamadığını da gösterir.
Kurulum
“Kurulum” başlıklı bölümcomposer require nextpdf/core:^3Başka bir uzantıya ihtiyacınız yoktur.
Kavramsal genel bakış
“Kavramsal genel bakış” başlıklı bölümHiyerarşi şöyledir:
RuntimeException └── NextPdfException (abstract, implements ContextAwareExceptionInterface) ├── InvalidConfigException ├── FontNotFoundException ├── FontParsingException ├── ImageProcessingException ├── WriterException ├── SignatureException ├── EncryptionException ├── HtmlParsingException ├── … (every domain exception under NextPDF\Exception) └── Strict\StrictModeViolation (abstract) ├── Strict\IncompatibleRenderingModeException └── Strict\OracleConformanceFailureKaynak koduna karşı doğrulanmış bu hiyerarşinin iki pratik sonucu vardır:
catch (NextPdfException $e)bloğu, katı mod ihlalleri dahil olmak üzereNextPDF\Exceptionaltındaki her istisnayı yakalar. Hepsi soyut tabandan türemiştir.- Kütüphanenin fırlatabileceği her şeyi yakalamaz.
NextPDF\Support\DegradedException,RuntimeExceptionsınıfından doğrudan türemiştir;NextPdfExceptionsınıfından değil. Dolayısıyla bircatch (NextPdfException $e)bloğu, bir düşürme ilkesi reddini yakalamaz. Bunu ele almak içinDegradedException(veya daha geniş kapsamlıRuntimeException) istisnasını açıkça yakalayın. Bu tarif, tek bir catch-all bloğunu eksiksiz kapsama olarak görmek yerine bu sınırı açık hale getirir.
NextPdfException::getContext(), snake_case anahtarlar ve yalnızca ilkel değerler ya da ilkel değer listeleri içeren bir array<string, mixed> döndürür. Bunu doğrudan bir PSR-3 günlükleyicisinin bağlam dizisine aktarabilirsiniz. PSR-3 §1.3, bir istisnanın 'exception' bağlam anahtarının altında yer almasını belirtir. NextPDF’in getContext() yöntemi, istisna nesnesinin kendisini değil, bu anahtarın yanına etki alanına özgü ayrıntılar ekler.
API yüzeyi
“API yüzeyi” başlıklı bölümBu API yüzeyi şu kaynaklardaki PHPDoc’tan alınır: NextPDF\Exception\NextPdfException, NextPDF\Contracts\ContextAwareExceptionInterface, somut etki alanı istisnaları (örneğin NextPDF\Exception\FontNotFoundException, getFontName() / getSearchPaths() / wasFallbackAttempted() ile) ve NextPDF\Support\DegradedException (Capability ve DegradationPolicy öğelerini taşır). Aşağıdaki örnekler NextPdfException::getContext() yöntemini ve istisnaya özel erişimcileri kullanır.
Kod örneği — Hızlı başlangıç
“Kod örneği — Hızlı başlangıç” başlıklı bölüm<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
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(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/out.pdf');} catch (NextPdfException $e) { // Every NextPDF\Exception\* (and strict-mode violation) lands here. // $e->getContext() is APM-safe structured detail. error_log($e->getMessage());}Kod örneği — Üretim
“Kod örneği — Üretim” başlıklı bölümTam örnek; ayrıntılı yakalamaları, yapılandırılmış bağlamı günlüğe kaydetmeyi ve DegradedException sınırını gösterir. Ayrıca test koşumunun çıktı kanalını da korur.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;use NextPDF\Contracts\ContextAwareExceptionInterface;use NextPDF\Exception\FontNotFoundException;use NextPDF\Exception\NextPdfException;use NextPDF\Support\DegradedException;
/** * A minimal PSR-3-shaped sink. In production this is your real logger; * the exception goes under the 'exception' key (PSR-3 §1.3) and the * NextPDF structured context is merged in as domain detail. * * @param array<string, mixed> $context */function logError(string $message, array $context): void{ fwrite(STDERR, $message . ' ' . json_encode($context, JSON_THROW_ON_ERROR) . "\n");}
$doc = Document::createStandalone();$doc->setTitle('Exception handling patterns');
try { $doc->addPage(); $doc->setFont('helvetica', 'B', 16); $doc->cell(0, 12, 'Exception-aware error handling', newLine: true);
// This call succeeds; the catch blocks below show the SHAPE of handling. $doc->setFont('helvetica', '', 11); $doc->cell(0, 8, 'Catch specifically, then fall back to the base.', newLine: true);} catch (FontNotFoundException $e) { // Most specific first: actionable, typed accessors. logError('Font missing — using a fallback face', [ 'exception' => $e::class, 'font_name' => $e->getFontName(), 'searched' => $e->getSearchPaths(), 'fallback' => $e->wasFallbackAttempted(), ]);} catch (NextPdfException $e) { // Catch-all for every NextPDF\Exception\* including strict violations. $context = ['exception' => $e::class]; if ($e instanceof ContextAwareExceptionInterface) { $context += $e->getContext(); } logError($e->getMessage(), $context);} catch (DegradedException $e) { // BOUNDARY: DegradedException extends RuntimeException directly, NOT // NextPdfException. The catch above would NOT have caught it. This // explicit block (or a broader RuntimeException) is required. logError('Capability degraded under the active policy', [ 'exception' => $e::class, 'capability' => $e->capability->id, 'policy' => $e->policy->value, ]);}
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/out.pdf');
fwrite(STDERR, "Document built; handlers wired.\n");STDOUT, koşum donanımı için boş kalır; PDF yalnızca NEXTPDF_COOKBOOK_OUTPUT hedefine yazılır.
Uç durumlar ve dikkat edilecek noktalar
“Uç durumlar ve dikkat edilecek noktalar” başlıklı bölüm- Yakalama bloklarını özelden → genele doğru sıralayın. PHP, uyumlu olan ilk
catchbloğuyla eşleşir. Bircatch (NextPdfException $e)bloğununcatch (FontNotFoundException $e)bloğundan önce yerleştirilmesi, özel bloğu erişilemez kod haline getirir. DegradedExceptionbirNextPdfExceptiondeğildir. Kaynak koduna karşı doğrulandığı üzere,RuntimeExceptionsınıfından türemiştir. Tek bircatch (NextPdfException $e), katı düşürme reddinin yayılmasına izin verir. Düşürme ilkesi devredeyken bunu (veyaRuntimeExceptionsınıfını) açıkça yakalayın.getContext()sözleşme gereği APM açısından güvenlidir. Anahtarlar snake_case biçimindedir. Değerler ilkel türler veya ilkel tür listeleridir; iç içe nesneler ya da kaynaklar içermez. Bunu doğrudan seri hale getirebilirsiniz. Asla belge baytları içermez.- İstisna iletilerini ayrıştırmayın. İletiler insanlar için okunabilirdir ve değişebilir. Kararlı makine yüzeyi olarak türlendirilmiş erişimcileri (
getFontName(),capability->idvb.) vegetContext()yöntemini kullanın. - Güncel olmayan sayı notu. Daha eski materyaller sabit bir “N etki alanı istisnası” değerinden söz edebilir. Hiyerarşi sürümler boyunca büyür. Sabit kodlanmış bir sayıya değil, her zaman
NextPdfExceptiontaban türüne veinstanceofkullanımına güvenin. - PSR-3 yer tutucuları dize olarak kalır. Günlüğe kaydederken iletiyi
{placeholder}belirteçleri içeren bir dize olarak tutun ve değerleri bağlam dizisine yerleştirin (PSR-3 §1.2). İstisna nesnesini iletinin içine koymayın.
Performans
“Performans” başlıklı bölümİstisna işleme, normal akışta ek maliyet getirmez. NextPDF yalnızca istisnai durumlarda istisna fırlatır ve getContext() çağrıldığında küçük bir dizi oluşturur. performance_budget (wall_ms: 2000, peak_mb: 96), rastgele belgeleri değil, bu tarife yönelik test koşumunu sınırlandırır.
Güvenlik notları
“Güvenlik notları” başlıklı bölümgetContext()günlük açısından güvenli olacak şekilde tasarlanmıştır: yalnızca ilkel türler içerir; belge yükü veya dosya baytı içermez. Bir günlük bağlamına eklediğiniz değerlerden yine de siz sorumlusunuz. Kullanıcı tarafından sağlanan her şeyi (örneğin bir dosya yolu) bir hedefe ulaşmadan önce günlük kaydı ilkenize göre temizleyin.- Ham istisna iletilerini, dosya sistemi düzenini sızdıracak biçimde son kullanıcılara göstermeyin. Genel bir ileti gösterin ve yapılandırılmış bağlamı sunucu tarafında günlüğe kaydedin.
Uygunluk
“Uygunluk” başlıklı bölüm| İfade | Belirtim | Madde | reference_id |
|---|---|---|---|
Bir istisna, PSR-3 günlük bağlamında exception anahtarının altında yer alır. | PSR-3 | §1.3 | |
| Günlük iletileri dize olarak kalır; yer tutucu adları bağlam anahtarlarıyla eşlenir. | PSR-3 | §1.2 | |
| Değişiklik tarihi her kaydetme işleminde yeniden oluşturulur, dolayısıyla çıktı bayt düzeyinde değil yapısal olarak kararlıdır. | ISO 32000-2 | §14.3 |
Bu tarif yapısal yeniden üretilebilirlik profiliyle doğrulanır. Çıktı, her kaydetme işleminde yeniden oluşturulan bir fragman (trailer) /ID değeri ve bir değişiklik tarihi taşır, dolayısıyla bayt düzeyinde özdeşlik elde edilemez. qpdf ile normalleştirilmiş yapı kararlı kalır.