Salta ai contenuti

Exception: gerarchia tipizzata delle eccezioni

Ogni eccezione sollevata da NextPDF estende un’unica classe base astratta, NextPdfException, quindi un singolo catch può gestire qualsiasi errore del motore. Ogni eccezione di dominio implementa ContextAwareExceptionInterface, esponendo campi diagnostici strutturati per logging e APM senza dover analizzare la stringa del messaggio.

Terminal window
composer require nextpdf/core:^3

La gerarchia si articola in tre livelli:

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 estende la classe SPL RuntimeException: intercettare RuntimeException include quindi anche gli errori di NextPDF, mentre intercettare NextPdfException limita l’ambito agli errori del motore. Per un ripristino mirato, intercettare una classe foglia. Il sotto-albero Strict\ raggruppa le violazioni della modalità di conformità sotto la classe astratta StrictModeViolation, che a sua volta estende NextPdfException.

Il contesto, non i codici stringa. NextPDF identifica un errore in base al tipo PHP, non tramite un codice di errore in forma di stringa. Nelle classi di eccezione non esiste alcuna costante di codice NPDF-####. Al suo posto, ContextAwareExceptionInterface::getContext() restituisce un array<string, mixed> di campi primitivi in snake_case, serializzabili in modo sicuro in un payload di log o APM. NextPdfException::getContext() restituisce [] per impostazione predefinita. Ogni eccezione di dominio ne esegue l’override con i campi pertinenti allo specifico errore. Ad esempio, FontNotFoundException::getContext() restituisce font_name, search_paths e fallback_attempted. WriterException restituisce output_path e writer_state. InvalidConfigException restituisce config_key, given_value e expected_type. Gli identificatori in forma di stringa separati e stabili NEXTPDF_W_* appartengono all’enum non fatale WarningCode del modulo Support, non alle eccezioni.

Azionabilità. Il docblock della classe di ogni eccezione di dominio indica chi può intervenire — sviluppatore, infrastruttura o chiamante della libreria. InvalidConfigException è un errore dello sviluppatore (correggere la configurazione). FontNotFoundException è un errore dello sviluppatore o dell’infrastruttura (verificare il percorso o i permessi del file). WriterException è un errore dell’infrastruttura (disco, permessi, flusso di output). NotImplementedException è un errore del chiamante (rimuovere la chiamata oppure vincolare la versione a una release che introduce il follow-up indicato). Diverse eccezioni dispongono di costruttori nominati per cause radice precise — SignatureException::ltvCapabilityMissing(), ::tsaRequired() e simili — così gli operatori vedono la causa effettiva anziché un messaggio generico.

SimboloTipoMembri principali
NextPDF\Contracts\ContextAwareExceptionInterfaceinterfacegetContext(): array<string, mixed>
NextPDF\Exception\NextPdfExceptionclasse astrattaestende RuntimeException; getContext() (predefinito [])
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\StrictModeViolationabstractestende NextPdfException
NextPDF\Exception\Strict\IncompatibleRenderingModeExceptionfinalestende StrictModeViolation

Elenco completo delle classi foglia (23): BarcodeEncoderNotFoundException, BarcodeException, CompressionException, ContentStreamBalanceException, CssParserLimitExceededException, CssResolutionBudgetExceededException, EncryptionException, FontNotFoundException, FontParsingException, GraphicsStateBalanceException, HtmlParsingException, ImageProcessingException, InvalidConfigException, LinearizationInvariantException, LinearizationUnimplementedException, MissingShadingResourceException, NotImplementedException, PageLayoutException, PdfRViolationException, SignatureException, TemplateException, UnsupportedAlgorithmException e WriterException.

Usare il tipo base per intercettare qualsiasi errore del motore.

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

Questo schema è mostrato in examples/15-exception-handling.php.

Gestire il ripristino a livello di classe foglia e inoltrare il contesto strutturato alla pipeline di 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;
}
}
  • L’ordine delle clausole catch è importante. Elencare le classi foglia prima di NextPdfException. Un catch (NextPdfException) inserito per primo intercetta ogni sottoclasse.
  • getContext() espone chiavi in snake_case e valori primitivi o elenchi di primitivi — nessun oggetto annidato — così il payload resta sempre sicuro in formato JSON.
  • Il metodo base NextPdfException::getContext() restituisce []. Una sottoclasse che non ne esegue l’override non espone alcun campo strutturato. In quel caso, affidarsi a getMessage().
  • NextPdfException è astratta — non è possibile istanziarla direttamente. Sollevare una classe foglia concreta.
  • NotImplementedException è intenzionalmente esplicita: segnala un’implementazione deliberatamente assente, non un errore transitorio. Non ritentarla.
  • Le eccezioni Strict\* segnalano una violazione del contratto in modalità di conformità, non un errore di runtime recuperabile. Trattarle come difetti di configurazione o di input.
  • Non esiste alcuna costante di codice di errore in forma di stringa. Effettuare la corrispondenza in base al tipo dell’eccezione. Inoltrare getContext() per i consumatori automatici.

La costruzione di un’eccezione richiede una singola allocazione di oggetto più lo sprintf che compone il messaggio — O(1). getContext() restituisce un piccolo array associativo costruito a partire da campi già presenti, O(1) rispetto al numero di campi. Le eccezioni appartengono al percorso di errore, non al percorso critico. Il costo è trascurabile rispetto al lavoro non riuscito. Il performance_budget predefinito per questa pagina di riferimento è wall_ms: 1500, peak_mb: 64.

I campi di contesto possono contenere dettagli derivati dal documento: FontNotFoundException include i percorsi di ricerca del filesystem, WriterException include il percorso di output, InvalidConfigException include il valore fornito. Sanificare le chiavi di contesto oppure consentirle tramite allowlist prima di inoltrarle a un sink di log non pienamente affidabile, poiché percorsi e valori possono rivelare la struttura del deployment o l’input dell’utente. I messaggi delle eccezioni sono leggibili dalle persone e possono includere gli stessi dettagli — non mostrare i messaggi grezzi agli utenti finali in un contesto sensibile dal punto di vista della sicurezza. SignatureException associa deliberatamente al messaggio la causa radice concreta (pacchetto mancante, URL TSA vuoto), così gli operatori effettuano il triage senza dover fare grep sui punti di chiamata. Tale dettaglio è destinato agli operatori, non agli utenti finali.

Questo modulo definisce il modello di errore del motore e non riporta alcuna citazione normativa di standard. Le eccezioni sollevate per violazioni degli standard — ad esempio PdfRViolationException o Strict\OracleConformanceFailure — fanno riferimento alla clausola che le governa nel modulo che rileva la violazione, non qui.

  • /modules/core/contracts/ContextAwareExceptionInterface, definizione
  • /modules/core/observability/ — inoltro di getContext() all’APM
  • /modules/core/config/InvalidConfigException, NotImplementedException
  • /modules/core/support/DegradedException; WarningCode (NEXTPDF_W_*)
  • /modules/core/event/InvalidConfigException da addListener()

Glossario: eccezione contestualizzata · politica di degradazione