getPrevious()
En PHP, $exception->getPrevious() recupera la excepción anterior lanzada, permitiendo encadenar excepciones para conservar la causa original.
Introducción
Exception::getPrevious() devuelve la excepción que se pasó como tercer argumento al constructor de una excepción PHP — la excepción que causó la actual. Está definida en la clase base Exception (y Error), por lo que todos los tipos de excepción de PHP la heredan.
Esta página explica qué devuelve getPrevious(), cómo construir una cadena de excepciones "envueltas", cómo recorrer esa cadena y los errores comunes que hay que evitar.
Sintaxis y valor de retorno
final public Throwable::getPrevious(): ?Throwable- Parámetros: ninguno.
- Devuelve: el
Throwableanterior (unaExceptionoError) si se estableció uno, de lo contrarionull. - El método es
final, por lo que no puede sobreescribirse en sus propias subclases de excepción.
La excepción "anterior" se establece al construir una excepción con un tercer argumento:
throw new RuntimeException("High-level failure", 0, $originalException);
// message ^code ^previousEjemplo básico
Al relanzar una excepción, pase la original como tercer argumento del constructor para que el contexto no se pierda:
<?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";
}
}
?>Salida:
Caught: Outer error
Caused by: Inner errorgetPrevious() devuelve el objeto $inner que se pasó, por lo que puede leer su mensaje, código o traza de pila exactamente como lo haría con cualquier excepción.
Por qué envolver excepciones
Un patrón habitual consiste en capturar una excepción técnica de bajo nivel (una consulta de base de datos fallida, un archivo inexistente) y relanzar una de alto nivel específica del dominio — sin descartar la 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";
}
?>Salida:
Unable to load user #42
Root cause: SQLSTATE[HY000]: connection refusedEsto mantiene los mensajes de error de alto nivel limpios y, al mismo tiempo, conserva el detalle técnico para el registro y la depuración.
Recorrer la cadena completa de excepciones
Una excepción anterior puede tener a su vez una excepción anterior. Para inspeccionar toda la cadena, itere mientras getPrevious() devuelva un valor distinto 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();
}
?>Salida:
Level 3: top-level error
Level 2: mid-level wrapper
Level 1: low-level causeErrores comunes
- Sin excepción anterior devuelve
null. Si crea una excepción sin tercer argumento,getPrevious()devuelvenull. Compruebe siempre con!== null(o en un bucle) antes de llamar a métodos sobre el resultado. - El tercer argumento del constructor es el anterior, no el código. La firma es
new Exception($message, $code, $previous). Un error frecuente es pasar la excepción anterior en la segunda posición, donde PHP espera un código entero. - Es de solo lectura. No existe
setPrevious(). La cadena queda fijada en el momento de la construcción, por lo que debe pasar la causa al crear la excepción envolvente. var_dump($e)ya muestra la cadena. Al convertir una excepción no capturada a string (o cuando PHP la imprime), la traza de la excepción anterior se incluye automáticamente —getPrevious()es para cuando necesita inspeccionarla en el código.
Métodos relacionados
getPrevious() es uno de los varios métodos de inspección que expone toda excepción PHP:
getMessage()— el mensaje de error legible por humanos.getCode()— el código de error numérico.getTrace()— la traza de pila como array.getTraceAsString()— la traza de pila como string.
Para una visión más amplia de try/catch y las clases de excepción personalizadas, consulte Excepciones PHP.
Resumen
getPrevious() recupera la excepción que causó la actual, lo que permite el encadenamiento de excepciones: capture un error de bajo nivel, lance uno significativo de alto nivel y conserve la causa raíz original para la depuración. Devuelve null cuando no se estableció ninguna excepción anterior, por lo que compruébelo — o itere sobre ello — antes de usar el resultado.