Exception : hiérarchie d’exceptions typées
Chaque exception levée par NextPDF étend une unique classe de base abstraite, NextPdfException, ce qui permet à un seul catch de gérer n’importe quelle erreur du moteur. Chaque exception de domaine implémente ContextAwareExceptionInterface et expose des champs de diagnostic structurés pour le logging et l’APM, sans analyser la chaîne du message.
Installation
Section intitulée « Installation »composer require nextpdf/core:^3Aperçu conceptuel
Section intitulée « Aperçu conceptuel »La hiérarchie comporte trois couches :
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\UnregisteredCssDeviationLa classe NextPdfException étend RuntimeException, issue de la SPL. Intercepter RuntimeException intercepte donc aussi les erreurs NextPDF. Intercepter NextPdfException limite la portée aux erreurs du moteur. Intercepte une classe feuille quand tu veux une reprise ciblée. Le sous-arbre Strict\ regroupe les violations du mode de conformité sous la classe abstraite StrictModeViolation, qui étend elle-même NextPdfException.
Le contexte, pas des codes sous forme de chaîne. NextPDF identifie une erreur par son type PHP, et non par un code d’erreur sous forme de chaîne. Les classes d’exception ne définissent aucune constante de code NPDF-####. À la place, ContextAwareExceptionInterface::getContext() renvoie un array<string, mixed> composé de champs primitifs en snake_case, que tu peux sérialiser sans risque dans une charge utile de log ou d’APM. NextPdfException::getContext() renvoie [] par défaut. Chaque exception de domaine le redéfinit avec les champs pertinents pour la défaillance concernée. Par exemple, FontNotFoundException::getContext() renvoie font_name, search_paths et fallback_attempted. WriterException renvoie output_path et writer_state. InvalidConfigException renvoie config_key, given_value et expected_type. Les identifiants de chaîne stables et distincts NEXTPDF_W_* appartiennent à l’énumération non fatale WarningCode du module Support, pas aux exceptions.
Actionnabilité. Le docblock de chaque exception de domaine indique qui peut agir sur l’erreur : développeur, infrastructure ou appelant de la bibliothèque. InvalidConfigException est une erreur de développeur (corrige la configuration). FontNotFoundException est une erreur de développeur ou d’infrastructure (vérifie le chemin ou les permissions du fichier). WriterException est une erreur d’infrastructure (disque, permissions, flux de sortie). NotImplementedException est une erreur du code appelant (supprime l’appel ou épingle une version qui fournit le suivi nommé). Plusieurs exceptions proposent des constructeurs nommés pour des causes racines précises — SignatureException::ltvCapabilityMissing(), ::tsaRequired(), et d’autres — afin que les opérateurs voient la cause réelle plutôt qu’un message générique.
Surface de l’API
Section intitulée « Surface de l’API »| Symbole | Nature | Membres clés |
|---|---|---|
NextPDF\Contracts\ContextAwareExceptionInterface | interface | getContext(): array<string, mixed> |
NextPDF\Exception\NextPdfException | classe abstraite | étend RuntimeException ; getContext() (par défaut []) |
NextPDF\Exception\InvalidConfigException | final | getConfigKey(), getGivenValue(), getExpectedType(), getContext() |
NextPDF\Exception\FontNotFoundException | final | getFontName(), getSearchPaths(), wasFallbackAttempted(), getContext() |
NextPDF\Exception\SignatureException | final | getCertInfo(), getSignatureLevel(), getDetail(), getContext() ; constructeurs nommés ltvCapabilityMissing(), tsaRequired(), httpClientMissing(), … |
NextPDF\Exception\WriterException | final | getOutputPath(), getWriterState(), getContext() |
NextPDF\Exception\PageLayoutException | final | getPageNumber(), getContext() |
NextPDF\Exception\NotImplementedException | final | $feature, $followUp |
NextPDF\Exception\Strict\StrictModeViolation | abstraite | étend NextPdfException |
NextPDF\Exception\Strict\IncompatibleRenderingModeException | final | étend StrictModeViolation |
Liste complète des feuilles (23) : BarcodeEncoderNotFoundException, BarcodeException, CompressionException, ContentStreamBalanceException, CssParserLimitExceededException, CssResolutionBudgetExceededException, EncryptionException, FontNotFoundException, FontParsingException, GraphicsStateBalanceException, HtmlParsingException, ImageProcessingException, InvalidConfigException, LinearizationInvariantException, LinearizationUnimplementedException, MissingShadingResourceException, NotImplementedException, PageLayoutException, PdfRViolationException, SignatureException, TemplateException, UnsupportedAlgorithmException, WriterException.
Exemple de code — Démarrage rapide
Section intitulée « Exemple de code — Démarrage rapide »Intercepte n’importe quelle erreur du moteur avec le type de base.
<?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());}Ce motif est vérifié par examples/15-exception-handling.php.
Exemple de code — Production
Section intitulée « Exemple de code — Production »Effectue la reprise au niveau de la classe feuille et transmets le contexte structuré au pipeline de logs.
<?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; }}Cas limites et pièges
Section intitulée « Cas limites et pièges »- L’ordre des catch compte. Liste les classes feuilles avant
NextPdfException. Uncatch (NextPdfException)placé en tête intercepte toutes les sous-classes. getContext()produit des clés en snake_case et des valeurs primitives ou des listes de primitives, sans objets imbriqués ; la charge utile reste donc toujours compatible JSON.- La méthode de base
NextPdfException::getContext()renvoie[]. Une sous-classe qui ne la redéfinit pas ne porte aucun champ structuré. Appuie-toi surgetMessage()dans ce cas. NextPdfExceptionest abstraite : tu ne peux pas l’instancier directement. Lève une feuille concrète.NotImplementedExceptionest volontairement bruyante : elle signale une implémentation délibérément absente, pas une défaillance transitoire. Ne retente pas l’opération.Strict\*: ces violations indiquent une rupture de contrat du mode de conformité, pas une erreur d’exécution récupérable. Traite-les comme des défauts de configuration ou d’entrée.- Il n’existe aucune constante de code d’erreur sous forme de chaîne. Fais la correspondance à partir du type de l’exception. Transmets
getContext()pour les consommateurs machine.
Performances
Section intitulée « Performances »La construction d’une exception se limite à une allocation d’objet, plus le sprintf qui construit le message : O(1). getContext() renvoie un petit tableau associatif construit à partir de champs déjà stockés, en O(1) par rapport au nombre de champs. Les exceptions relèvent du chemin d’échec, pas du chemin critique. Leur coût est négligeable face au travail qui a échoué. Le performance_budget par défaut de cette page de référence est wall_ms: 1500, peak_mb: 64.
Notes de sécurité
Section intitulée « Notes de sécurité »Les champs de contexte peuvent transporter des détails issus du document : FontNotFoundException inclut les chemins de recherche du système de fichiers, WriterException inclut le chemin de sortie, InvalidConfigException inclut la valeur fournie. Nettoie ou filtre par liste d’autorisation les clés de contexte avant de les transmettre à une destination de logs peu fiable, car les chemins et les valeurs peuvent révéler la topologie du déploiement ou l’entrée utilisateur. Les messages d’exception sont lisibles par un humain et peuvent inclure les mêmes détails : n’expose pas les messages bruts aux utilisateurs finaux dans un contexte sensible pour la sécurité. SignatureException lie délibérément la cause racine concrète (package manquant, URL TSA vide) au message, afin que les opérateurs puissent diagnostiquer sans devoir rechercher dans les sites d’appel avec grep. Ce détail s’adresse aux opérateurs, pas aux utilisateurs finaux.
Conformité
Section intitulée « Conformité »Ce module est un modèle d’erreurs du moteur et ne contient aucune citation de standard normatif. Les exceptions levées pour des violations de standards — par exemple PdfRViolationException ou Strict\OracleConformanceFailure — référencent leur clause applicable dans le module qui détecte la violation, pas ici.
Voir aussi
Section intitulée « Voir aussi »/modules/core/contracts/—ContextAwareExceptionInterface, sa définition/modules/core/observability/— transmission degetContext()vers l’APM/modules/core/config/—InvalidConfigException,NotImplementedException/modules/core/support/—DegradedException;WarningCode(NEXTPDF_W_*)/modules/core/event/—InvalidConfigExceptionémise paraddListener()
Glossaire : exception sensible au contexte · politique de dégradation