W3docs

getPrevious()

In PHP, $exception->getPrevious() recupera l'eccezione precedente lanciata, utile per il concatenamento delle eccezioni e il debug.

Introduzione

Exception::getPrevious() restituisce l'eccezione passata come terzo argomento al costruttore di un'eccezione PHP — l'eccezione che ha causato quella corrente. È definita nella classe base Exception (e Error), quindi ogni tipo di eccezione PHP la eredita.

Questa pagina illustra cosa restituisce getPrevious(), come costruire una catena di eccezioni "avvolte", come percorrere tale catena e gli errori comuni da evitare.

Sintassi e valore di ritorno

final public Throwable::getPrevious(): ?Throwable
  • Parametri: nessuno.
  • Restituisce: il precedente Throwable (un'Exception o un Error) se ne è stato impostato uno, altrimenti null.
  • Il metodo è final, quindi non è possibile sovrascriverlo nelle proprie sottoclassi di eccezione.

L'eccezione "precedente" viene impostata quando si costruisce un'eccezione con un terzo argomento:

throw new RuntimeException("High-level failure", 0, $originalException);
//                          message            ^code  ^previous

Esempio base

Quando si rilancia un'eccezione, passa l'originale come terzo argomento del costruttore in modo che il contesto non vada perso:

<?php
try {
    try {
        throw new Exception("Inner error");
    } catch (Exception $inner) {
        // Wrap the low-level error in a more meaningful one,
        // keeping the original as "previous".
        throw new Exception("Outer error", 0, $inner);
    }
} catch (Exception $e) {
    echo "Caught: " . $e->getMessage() . "\n";

    $previous = $e->getPrevious();
    if ($previous !== null) {
        echo "Caused by: " . $previous->getMessage() . "\n";
    }
}
?>

Output:

Caught: Outer error
Caused by: Inner error

getPrevious() restituisce l'oggetto $inner che hai passato, così puoi leggerne il messaggio, il codice o lo stack trace esattamente come faresti con qualsiasi eccezione.

Perché avvolgere le eccezioni

Un pattern comune consiste nel catturare un'eccezione tecnica di basso livello (una query al database fallita, un file mancante) e rilanciare un'eccezione di livello superiore e specifica del dominio — senza perdere la causa originale:

<?php
function loadUser(int $id): array
{
    try {
        // Pretend this talks to a database and fails.
        throw new RuntimeException("SQLSTATE[HY000]: connection refused");
    } catch (RuntimeException $dbError) {
        // Callers care about "could not load user", not SQL internals,
        // but we keep the SQL error available via getPrevious().
        throw new RuntimeException("Unable to load user #$id", 0, $dbError);
    }
}

try {
    loadUser(42);
} catch (RuntimeException $e) {
    echo $e->getMessage() . "\n";
    echo "Root cause: " . $e->getPrevious()->getMessage() . "\n";
}
?>

Output:

Unable to load user #42
Root cause: SQLSTATE[HY000]: connection refused

In questo modo i messaggi di errore di alto livello restano chiari, preservando al contempo il dettaglio tecnico per il logging e il debug.

Percorrere l'intera catena di eccezioni

Un'eccezione precedente può a sua volta avere una propria eccezione precedente. Per ispezionare l'intera catena, esegui un ciclo finché getPrevious() restituisce un valore non null:

<?php
$a = new Exception("Level 1: low-level cause");
$b = new Exception("Level 2: mid-level wrapper", 0, $a);
$c = new Exception("Level 3: top-level error", 0, $b);

$current = $c;
while ($current !== null) {
    echo $current->getMessage() . "\n";
    $current = $current->getPrevious();
}
?>

Output:

Level 3: top-level error
Level 2: mid-level wrapper
Level 1: low-level cause

Errori comuni

  • Nessuna eccezione precedente restituisce null. Se crei un'eccezione senza terzo argomento, getPrevious() restituisce null. Verifica sempre con !== null (o un ciclo) prima di chiamare metodi sul risultato.
  • Il terzo argomento del costruttore è l'eccezione precedente, non il codice. La firma è new Exception($message, $code, $previous). Un errore frequente è passare l'eccezione precedente nel secondo slot, dove PHP si aspetta un codice intero.
  • È di sola lettura. Non esiste setPrevious(). La catena è fissata al momento della costruzione, quindi devi passare la causa quando crei l'eccezione di avvolgimento.
  • var_dump($e) mostra già la catena. Quando si converte un'eccezione non catturata in stringa (o si lascia che PHP la stampi), la traccia dell'eccezione precedente ("Caused by") è inclusa automaticamente — getPrevious() serve quando è necessario ispezionarla nel codice.

Metodi correlati

getPrevious() è uno dei vari metodi di ispezione esposti da ogni eccezione PHP:

Per una visione più ampia di try/catch e delle classi di eccezione personalizzate, consulta PHP Exceptions.

getPrevious() recupera l'eccezione che ha causato quella corrente, abilitando il concatenamento delle eccezioni: cattura un errore di basso livello, lancia uno significativo di alto livello e mantieni comunque la causa originale per il debug. Restituisce null quando non è stata impostata alcuna eccezione precedente, quindi verifica tale condizione — o esegui un ciclo — prima di utilizzare il risultato.

Pratica

Pratica
Cosa fa la funzione PHP getPrevious()?
Cosa fa la funzione PHP getPrevious()?
Was this page helpful?