Excepciones personalizadas en PHP
CategoriasPHPProgramación

Excepciones personalizadas

Excepciones personalizadas en PHP

En el anterior artículo que escribí sobre qué son las excepciones en PHP, me olvidé (intencionadamente) de mostrar cómo crear nuestras propias excepciones personalizadas heredando de la clase base Exception.

El objetivo con este artículo es explicar un poco más detalladamente porqué deberíamos de hacerlo y cómo hacerlo.

Es bastante simple, empecemos 😊

Como ya vimos, PHP nos ofrece unas cuantas excepciones predefinidas y si no tenemos suficiente, podemos optar por usar la clase base Exception con nuestros propios mensajes de error. Sin embargo, si la aplicación crece o queremos hacer las cosas bien, lo correcto es crear nuestras propias excepciones para que se adapten a cada necesidad especifica de nuestra aplicación y de esa manera conseguir un manejo de errores más claro y descriptivo a la par de hacer el código más fácil de entender y mantener.

La idea principal por la cual es recomendable crear nuestras propias excepciones es la claridad del código y la especificidad, es decir, nos permite manejar los errores de forma más precisa.

Otro punto a favor, es que podemos agrupar las excepciones en una jerarquía de clases (lo veremos a continuación).

Vayamos al grano, imaginemos que tenemos una web donde solo queremos confirmar la edad del usuario, pero solo permitimos entrar a personas que tengan entre 20 y 40 años. Si, ya sé que es un ejemplo ridículo y no me preguntes porque he elegido este, pero al menos a modo de ejemplo funciona bien.

<?php

class EdadInvalidaException extends Exception
{
    public function __construct($message = "La edad proporcionada no es válida", $code = 0, Exception $previous = null)
    {
        // Llamamos al constructor de la clase base Exception
        parent::__construct($message, $code, $previous);
    }

    public function unaFuncionCualquiera()
    {
        return "Debes de tener entre 20 y 40 años. Somos asi de raros ha-ha!"; // Mensaje personalizado para EdadInvalidaException
    }
}

function comprobarEdad($age)
{
    if ($age < 20 || $age > 40) {
        throw new EdadInvalidaException("La edad $age no es válida.");
    }
    return "La edad es $age";
}

try {
    echo comprobarEdad(18);
} catch (EdadInvalidaException $e) {
    echo "Error: " . $e->getMessage() . "\n";
    echo $e->unaFuncionCualquiera();
}

Como vemos:

1º Hemos creado una clase EdadInvalidaException que extiende de Exception.

2º La función comprobarEdad() lanza esta excepción si el valor de la edad no es correcto.

3º En el bloque catch, capturamos específicamente la excepción EdadInvalidaException, lo que permite manejar este error en particular y acceder a métodos personalizados como “unaFuncionCualquiera()” la cual imprime un simple mensaje.

Mencionar también y muy importante que siempre llamemos al constructor de la clase base Exception.

Como ves, crear nuestras propias excepciones personalizadas en principio no tiene ningún misterio, es bastante fácil.

Ahora veamos, donde reside quizá, la potencia de tener nuestras propias excepciones.

Jerarquía de Excepciones Personalizadas

Como siempre, es mejor verlo con un ejemplo y a ser posible sencillo para que quede clara la idea 😉

Imagina un sistema de autenticación básico en el cual nos gustaría controlar los distintos errores que se produzcan.

Por ejemplo, podemos tener una clase llamada AuthException la cual sería nuestra clase base para todas las excepciones relacionadas con la autenticación.

Por otro lado, podríamos tener otro par de clases más, una llamada InvalidCredentialsException para los errores de credenciales y otra AccountLockedException para errores relacionados con cuentas bloqueadas.

# Jerarquia de excepciones
// Clase base para excepciones de autenticación
class AuthException extends Exception {}

// Excepción para credenciales incorrectas
class InvalidCredentialsException extends AuthException
{
    public function __construct($message = "Las credenciales son incorrectas", $code = 1001, Exception $previous = null)
    {
        parent::__construct($message, $code, $previous);
    }
}

// Excepción para cuenta bloqueada
class AccountLockedException extends AuthException
{
    public function __construct($message = "La cuenta está bloqueada", $code = 1002, Exception $previous = null)
    {
        parent::__construct($message, $code, $previous);
    }
}

En principio como ves es bastante sencillo, no tiene ningún misterio.

Respecto a la propiedad $code, recuerda que nos sirve para categorizar los diferentes tipos de error. Evidentemente estos códigos son definidos por nosotros según nuestras preferencias o necesidades.

Para usar nuestras excepciones, podríamos simular una función de login de administrador:

function loginAdmin($username, $password)
{
    // Simulación de credenciales incorrectas
    if ($username !== "admin" || $password !== "1234") {
        throw new InvalidCredentialsException();
    }

    // Simulación de cuenta bloqueada
    $bloqueo = true; // Supongamos que la cuenta está bloqueada
    if ($bloqueo) {
        throw new AccountLockedException();
    }

    return "Autenticación exitosa";
}

try {
    echo loginAdmin("pepe", "pepito123");
} catch (InvalidCredentialsException $e) {
    echo "Error: " . $e->getMessage() . " (Código: " . $e->getCode() . ")";
} catch (AccountLockedException $e) {
    echo "Error: " . $e->getMessage() . " (Código: " . $e->getCode() . ")";
} catch (AuthException $e) {
    echo "Error de autenticación: " . $e->getMessage();
}

Como ves, InvalidCredentialsException y AccountLockedException son excepciones especificas que heredan de la excepción base AuthException.

Después, en el bloque try-catch capturamos cada tipo de excepción por separado, pero también llamamos a AuthException para capturar cualquier otro error relacionado con la autenticación.

Una vez más puedes observar que es bastante sencillo. Solo se trata de heredar de la clase base Exception y llamar al constructor padre. A partir de ahí podemos hacer lo que queramos.

Las ventajas de crear nuestras excepciones personalizadas es que hace el código más claro, especialmente en aplicaciones grandes o complejas donde un manejo más específico de los errores puede mejorar la claridad y control de los mismos. Como hemos visto también nos permite agrupar las excepciones en una jerarquía de clases, permitiendo agrupar errores similares bajo una clase base común facilitando la gestión de múltiples errores relacionados.

Otra ventaja es que facilita la depuración, ya que al proporcionar mensajes específicos nos permite rastrear los problemas de forma más efectiva, lo cual es especialmente útil para la depuración y sobra decir también, que tener excepciones personalizadas facilita el mantenimiento y la escalabilidad/evolución de nuestra aplicación.

Y por ahora esto sería todo. Espero te haya sido útil esta breve introducción a las excepciones personalizadas en PHP.

Sobre el autor

Comparte:

Este artículo está publicado bajo una licencia Creative Commons Atribución-CompartirIgual 4.0 Internacional . Puedes compartirlo y adaptarlo, incluso con fines comerciales, siempre que cites al autor y mantengas esta misma licencia.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Información básica sobre protección de datos
Responsable Óscar Martínez +info...
Finalidad Gestionar y moderar los comentarios +info...
Legitimación Consentimiento del interesado. +info...
Destinatarios No se cederán datos a terceros, salvo obligación legal +info...
Derechos Acceder, rectificar y cancelar los datos, así como otros derechos. +info...
Información adicional Puedes consultar la información adicional y detallada sobre protección de datos en nuestra página de política de privacidad.

Este sitio esta protegido por reCAPTCHA y laPolítica de privacidady losTérminos del servicio de Googlese aplican.

El periodo de verificación de reCAPTCHA ha caducado. Por favor, recarga la página.