Fehler mit der NextPDF-Ausnahmehierarchie behandeln
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“NextPDF wirft bei Ausnahmezuständen typisierte Ausnahmen. Es versteckt Fehler nie hinter einem Rückgabewert false oder null. Jede Domänenausnahme erweitert eine abstrakte Basisklasse, NextPdfException, und stellt strukturierten Diagnosekontext über ContextAwareExceptionInterface bereit. Diese Anleitung zeigt Ihnen, wie Sie in der richtigen Granularität abfangen und den strukturierten Kontext für eine APM-Pipeline (Application Performance Monitoring) loggen. Sie weist außerdem darauf hin, welche Fehler ein einzelner pauschaler Catch-Block nicht abdeckt.
Installation
Abschnitt betitelt „Installation“composer require nextpdf/core:^3Eine zusätzliche Extension ist nicht erforderlich.
Konzeptioneller Überblick
Abschnitt betitelt „Konzeptioneller Überblick“Die Hierarchie sieht so aus:
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\OracleConformanceFailureDiese Hierarchie hat zwei praktische Konsequenzen, die beide anhand des Quellcodes geprüft wurden:
catch (NextPdfException $e)fängt jede Ausnahme unterNextPDF\Exceptionab, einschließlich der Strict-Mode-Verstöße. Sie alle erweitern die abstrakte Basis.- Es fängt nicht alles ab, was die Bibliothek werfen kann.
NextPDF\Support\DegradedExceptionerweitertRuntimeExceptiondirekt, nichtNextPdfException. Eincatch (NextPdfException $e)fängt eine Ablehnung durch die Degradation-Policy also nicht ab. Um diesen Fall zu behandeln, fangen SieDegradedException(oder das breitereRuntimeException) explizit ab. Diese Anleitung benennt diese Grenze ausdrücklich, statt vorzugeben, ein einzelner pauschaler Catch-Block decke alles ab.
NextPdfException::getContext() gibt ein array<string, mixed> mit snake_case-Schlüsseln und ausschließlich primitiven Werten (oder Listen von Primitiven) zurück, sodass es sich direkt sicher in das Kontext-Array eines PSR-3-Loggers serialisieren lässt. PSR-3 §1.3 legt eine Ausnahme unter den Kontext-Schlüssel 'exception' ab. Die Methode getContext() von NextPDF ergänzt daneben Domänendetails, nicht das Ausnahmeobjekt selbst.
API-Oberfläche
Abschnitt betitelt „API-Oberfläche“Diese API-Oberfläche wird aus dem PHPDoc von NextPDF\Exception\NextPdfException, NextPDF\Contracts\ContextAwareExceptionInterface, den konkreten Domänenausnahmen (zum Beispiel NextPDF\Exception\FontNotFoundException, mit getFontName() / getSearchPaths() / wasFallbackAttempted()) und NextPDF\Support\DegradedException (die Capability und DegradationPolicy trägt) generiert. Die unten verwendeten Member sind NextPdfException::getContext() und die ausnahmespezifischen Accessor-Methoden.
Codebeispiel – Schnellstart
Abschnitt betitelt „Codebeispiel – Schnellstart“<?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());}Codebeispiel – Produktion
Abschnitt betitelt „Codebeispiel – Produktion“Das vollständige Beispiel zeigt granulares Abfangen, das Logging strukturierten Kontextes und die Grenze der DegradedException. Es respektiert den Ausgabekanal des Harness.
<?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 bleibt für das Harness frei; das PDF geht ausschließlich an NEXTPDF_COOKBOOK_OUTPUT.
Randfälle & Fallstricke
Abschnitt betitelt „Randfälle & Fallstricke“- Ordnen Sie Catch-Blöcke vom Spezifischen zum Allgemeinen → an. PHP trifft den ersten kompatiblen
catch. Eincatch (NextPdfException $e), der vorcatch (FontNotFoundException $e)steht, macht den spezifischen Block zu totem Code. DegradedExceptionist keineNextPdfException. Anhand des Quellcodes geprüft, erweitert sieRuntimeException. Ein einzelnescatch (NextPdfException $e)lässt eine Strict-Degradation-Ablehnung ungefangen durchlaufen. Fangen Sie sie (oderRuntimeException) explizit ab, wenn eine Degradation-Policy aktiv ist.getContext()ist laut Vertrag APM-sicher. Schlüssel sind snake_case. Werte sind Primitive oder Listen von Primitiven, ohne verschachtelte Objekte und ohne Ressourcen. Sie können es direkt serialisieren, und es enthält nie Dokument-Bytes.- Parsen Sie keine Ausnahme-Nachrichten. Nachrichten sind menschenlesbar und können sich ändern. Die typisierten Accessoren (
getFontName(),capability->idund so weiter) undgetContext()sind die stabile maschinelle Oberfläche. - Vorsicht bei veralteten Anzahlen. Älteres Material nennt womöglich eine feste „N Domänen-Ausnahmen“-Zahl. Die Hierarchie wächst über die Releases hinweg. Verlassen Sie sich auf den Basistyp
NextPdfExceptionundinstanceof, nie auf eine fest codierte Anzahl. - PSR-3-Placeholder (Platzhalter) bleiben Strings. Halten Sie die Nachricht beim Loggen als String mit
{placeholder}-Tokens und legen Sie die Werte in das Kontext-Array (PSR-3 §1.2). Interpolieren Sie das Ausnahmeobjekt nicht in die Nachricht.
Performance
Abschnitt betitelt „Performance“Die Ausnahmebehandlung verursacht im Normalbetrieb keine Kosten. NextPDF wirft nur bei Ausnahmezuständen, und getContext() baut bei Bedarf ein kleines Array auf. Das performance_budget (wall_ms: 2000, peak_mb: 96) begrenzt den Harness-Lauf dieser Anleitung, nicht beliebige Dokumente.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“getContext()ist so entworfen, dass es für Logs sicher ist: nur Primitive, kein Dokument-Payload, keine Datei-Bytes. Für Werte, die Sie einem Log-Kontext hinzufügen, sind Sie dennoch selbst verantwortlich. Bereinigen Sie alles, was Benutzer liefern (zum Beispiel einen Dateipfad), gemäß Ihrer Logging-Policy, bevor es einen Sink erreicht.- Geben Sie rohe Ausnahme-Nachrichten nicht so an Endnutzer aus, dass sie das Dateisystem-Layout preisgeben. Zeigen Sie eine generische Nachricht an und loggen Sie den strukturierten Kontext serverseitig.
Konformität
Abschnitt betitelt „Konformität“| Aussage | Spezifikation | Abschnitt | reference_id |
|---|---|---|---|
Eine Ausnahme gehört im PSR-3-Log-Kontext unter den Schlüssel exception. | PSR-3 | §1.3 | |
| Log-Nachrichten bleiben Strings; Placeholder-Namen werden auf Kontext-Schlüssel abgebildet. | PSR-3 | §1.2 | |
| Das Änderungsdatum wird bei jedem Speichern neu erzeugt, sodass die Ausgabe strukturell (nicht bytegenau) stabil ist. | ISO 32000-2 | §14.3 |
Diese Anleitung wird mit dem strukturellen Reproduzierbarkeitsprofil geprüft. Die Ausgabe trägt ein Trailer-/ID und ein Änderungsdatum, die bei jedem Speichern neu erzeugt werden, sodass Byteidentität nicht erreichbar ist. Die mit qpdf normalisierte Struktur ist stabil.