W3docs

set_exception_handler()

Cómo set_exception_handler() de PHP registra un manejador global para excepciones no capturadas, con firma, valor de retorno, ejemplo y buenas prácticas.

Introducción

set_exception_handler() registra una función que PHP invoca cada vez que una excepción no capturada llega al nivel superior del script. Normalmente una excepción no capturada produce un error fatal y un volcado de pila predeterminado; un manejador global permite reemplazar eso con registro consistente, una página de error amigable o alertas — en un solo lugar, para toda la aplicación. Esta página cubre la firma de la función, lo que devuelve, un ejemplo ejecutable, los casos que no cubre y los puntos a tener en cuenta.

Si necesitas antes los conceptos básicos de lanzar y capturar excepciones, comienza con Excepciones en PHP y el capítulo try/catch.

¿Cuándo se llama al manejador?

Una excepción normal es capturada por el bloque catch más cercano que coincida. El manejador global solo se ejecuta cuando ningún bloque catch coincide — la excepción "escapa" hasta el nivel superior del script:

try {
    throw new RuntimeException('handled here');
} catch (RuntimeException $e) {
    // caught locally — the global handler never runs
}

throw new RuntimeException('nothing catches this'); // → global handler runs, then script ends

Después de que el manejador retorna, la ejecución no se reanuda — el script termina. Por lo tanto, el manejador es tu última oportunidad para registrar y presentar el fallo de forma limpia, no una manera de recuperarse y continuar.

Firma y valor de retorno

set_exception_handler(?callable $callback): ?callable
  • $callback — un callable que acepta el objeto lanzado como único argumento. Desde PHP 7 toda excepción y error implementa Throwable, por lo que debes indicar el tipo del parámetro como Throwable (no solo Exception) para capturar también instancias de Error como TypeError.
  • Devuelve el manejador previamente registrado (o null si no había ninguno), que puedes conservar para restaurarlo después. Pasar null elimina el manejador.

Ejemplo ejecutable

El script a continuación registra un manejador, lo activa con una excepción no capturada e imprime un mensaje formateado. Escribe en el error estándar mediante error_log() sin destino, por lo que es totalmente portable:

<?php

function appExceptionHandler(Throwable $e): void
{
    $message = sprintf(
        "Uncaught %s: %s in %s on line %d",
        get_class($e),
        $e->getMessage(),
        $e->getFile(),
        $e->getLine()
    );

    error_log($message);            // goes to the SAPI error log / stderr
    echo "Something went wrong.\n"; // user-facing message
}

set_exception_handler('appExceptionHandler');

throw new RuntimeException('Database is unreachable');

Salida (la línea de error_log va a stderr, el echo a stdout):

Something went wrong.

con una línea como Uncaught RuntimeException: Database is unreachable in /path/to/script.php on line 19 en el registro de errores.

Lo que NO maneja

set_exception_handler() solo intercepta excepciones no capturadas. No captura:

  • Errores fatales, errores de análisis o advertencias — esos pasan por set_error_handler() (para errores capturables) o register_shutdown_function() (para errores fatales).
  • Excepciones que ya son capturadas por un bloque try/catch local.

Para errores que no son excepciones, como advertencias y avisos, registra un manejador separado con set_error_handler().

Restaurar el manejador anterior

restore_exception_handler() revierte al manejador que estaba activo antes de tu última llamada a set_exception_handler(). Úsalo cuando un manejador personalizado deba aplicarse solo a un bloque específico de código:

<?php

set_exception_handler(function (Throwable $e) {
    echo "Custom: {$e->getMessage()}\n";
});

// ... code that should use the custom handler ...

restore_exception_handler(); // back to the default behavior

Importante: tu manejador no debe lanzar una nueva excepción. Si lo hace, PHP no puede despacharla de nuevo y genera un error fatal en su lugar.

Buenas prácticas para usar set_exception_handler

Al usar set_exception_handler, hay algunas buenas prácticas que debes seguir para garantizar que tu aplicación maneje los errores de manera efectiva:

  1. Indica el tipo del parámetro del manejador como Throwable para capturar tanto subtipos de Exception como de Error (PHP 7+).
  2. Asegúrate de que el manejador nunca lance una nueva excepción — eso genera un error fatal irrecuperable.
  3. Registra suficiente contexto para diagnosticar el fallo: clase de la excepción, mensaje, archivo, línea y el seguimiento de pila de $e->getTraceAsString().
  4. Mantén el mensaje orientado al usuario de forma genérica; nunca expongas trazas de pila ni mensajes a los usuarios finales en producción.
  5. Registra el manejador lo antes posible (por ejemplo, en un archivo de arranque) para que cubra toda la solicitud.
  6. Combínalo con set_error_handler() y register_shutdown_function() para cubrir también advertencias, avisos y errores fatales.
  7. Usa restore_exception_handler() para revertir al manejador anterior cuando uno personalizado deba estar limitado a un bloque de código.

Conclusión

set_exception_handler() te ofrece un único lugar para manejar todas las excepciones no capturadas en una aplicación — convirtiendo un error fatal en bruto en registro consistente y un mensaje limpio para el usuario. Recuerda sus límites: solo se ejecuta para excepciones no capturadas, la ejecución se detiene después, y el manejador en sí nunca debe lanzar. Combínalo con set_error_handler() para advertencias, trigger-error para señales de error personalizadas, y restore_exception_handler() para manejo con alcance limitado, y así construir un reporte de errores robusto.

Práctica

Práctica
¿Qué hace la función set_exception_handler() en PHP?
¿Qué hace la función set_exception_handler() en PHP?
Was this page helpful?