getPrevious()
Em PHP, a função $exception->getPrevious() recupera a exceção anterior que foi lançada. Saiba como encadear exceções com exemplos práticos.
Introdução
Exception::getPrevious() retorna a exceção que foi passada como terceiro argumento para um construtor de exceção PHP — a exceção que causou a atual. Ela é definida na classe base Exception (e Error), portanto todo tipo de exceção PHP a herda.
Esta página aborda o que getPrevious() retorna, como construir uma cadeia de exceções "encapsuladas", como percorrer essa cadeia e os erros comuns a evitar.
Sintaxe e valor de retorno
final public Throwable::getPrevious(): ?Throwable- Parâmetros: nenhum.
- Retorna: o
Throwableanterior (umaExceptionouError) se um foi definido, caso contrárionull. - O método é
final, portanto não é possível sobrescrevê-lo em suas próprias subclasses de exceção.
A exceção "anterior" é definida quando você constrói uma exceção com um terceiro argumento:
throw new RuntimeException("High-level failure", 0, $originalException);
// message ^code ^previousExemplo básico
Quando você relança uma exceção, passe a original como o terceiro argumento do construtor para que o contexto não seja perdido:
<?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";
}
}
?>Saída:
Caught: Outer error
Caused by: Inner errorgetPrevious() retorna o objeto $inner que você passou, portanto você pode ler sua mensagem, código ou rastreamento de pilha exatamente como faria com qualquer exceção.
Por que encapsular exceções
Um padrão comum é capturar uma exceção técnica de baixo nível (uma consulta de banco de dados com falha, um arquivo ausente) e relançar uma exceção de domínio de nível superior — sem descartar a causa original:
<?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";
}
?>Saída:
Unable to load user #42
Root cause: SQLSTATE[HY000]: connection refusedIsso mantém suas mensagens de erro de alto nível limpas, preservando o detalhe técnico para registro e depuração.
Percorrendo a cadeia completa de exceções
Uma exceção anterior pode ela mesma ter uma exceção anterior. Para inspecionar toda a cadeia, faça um loop enquanto getPrevious() retornar um valor diferente de 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();
}
?>Saída:
Level 3: top-level error
Level 2: mid-level wrapper
Level 1: low-level causeArmadilhas comuns
- Sem exceção anterior retorna
null. Se você criar uma exceção sem um terceiro argumento,getPrevious()retornanull. Sempre verifique com!== null(ou em um loop) antes de chamar métodos no resultado. - O terceiro argumento do construtor é o anterior, não o código. A assinatura é
new Exception($message, $code, $previous). Um erro frequente é passar a exceção anterior no segundo slot, onde PHP espera um código inteiro. - É somente leitura. Não existe
setPrevious(). A cadeia é fixada no momento da construção, portanto você deve passar a causa ao criar a exceção encapsuladora. var_dump($e)já exibe a cadeia. Quando você converte uma exceção não capturada para string (ou deixa o PHP imprimi-la), o rastreamento da exceção anterior é incluído automaticamente —getPrevious()serve para quando você precisa inspecioná-la no código.
Métodos relacionados
getPrevious() é um dos vários métodos de inspeção que toda exceção PHP expõe:
getMessage()— a mensagem de erro legível por humanos.getCode()— o código de erro numérico.getTrace()— o rastreamento de pilha como um array.getTraceAsString()— o rastreamento de pilha como uma string.
Para uma visão mais ampla de try/catch e classes de exceção personalizadas, consulte Exceções PHP.
Resumo
getPrevious() recupera a exceção que causou a atual, permitindo o encadeamento de exceções: capture um erro de baixo nível, lance um de alto nível com significado, e ainda mantenha a causa raiz original para depuração. Ele retorna null quando nenhuma exceção anterior foi definida, portanto verifique isso — ou faça um loop — antes de usar o resultado.