java-crear-excepciones-propias-custom

Cómo crear excepciones propias en Java

  • 3 min

Una excepción propia es un tipo de excepción que expresa un fallo específico del dominio de la aplicación.

Java tiene muchas excepciones listas para usar, como IOException, NullPointerException o IllegalArgumentException.

Pero, ¿qué pasa si estás programando un sistema bancario y un usuario intenta sacar más dinero del que tiene? Podrías lanzar un IllegalArgumentException, sí. Pero eso es muy genérico. No explica por qué ha fallado la operación en el contexto de tu negocio.

Lo ideal sería lanzar una SaldoInsuficienteException.

Crear tus propias excepciones permite que tu código hable el idioma de tu negocio, haciendo que los errores sean más fáciles de entender y de gestionar.

Cómo crear una excepción

Técnicamente, crear una excepción es ridículamente fácil. Solo tienes que crear una clase y hacer que herede de una de las madres.

// Opción A: Excepción Checked (Obliga a capturar)
public class SaldoInsuficienteException extends Exception {

    public SaldoInsuficienteException(String mensaje) {
        super(mensaje); // Pasamos el mensaje al padre (Exception)
    }
}
Copied!

Ya está. Ahora puedes usarla en tu código:

throw new SaldoInsuficienteException("Te faltan 50 euros");
Copied!

Elegir entre Exception y RuntimeException

Al crear una excepción debes decidir si el llamador estará obligado a declararla o capturarla:

Extender de Exception (checked)

Eliges esta opción cuando el error es un evento previsible del negocio del que nos podemos recuperar. Quieres obligar al programador que use tu método a pensar qué hacer si esto ocurre.

  • Ejemplo: SaldoInsuficienteException.

  • Por qué: Es muy probable que un usuario intente sacar demasiado dinero. Si ocurre, queremos obligar a la interfaz gráfica a mostrar un mensaje bonito: “Saldo insuficiente, prueba con menos cantidad”.

Extender de RuntimeException (unchecked)

Eliges esta opción cuando el error indica un bug, un uso incorrecto de la API o un estado irrecuperable. No quieres obligar a poner try-catch porque, si esto pasa, el programador debería arreglar su código, no capturar el error.

  • Ejemplo: CuentaBloqueadaException (si es un estado fatal) o CantidadNegativaException.

  • Por qué: Si alguien intenta ingresar -100 euros, es un fallo de lógica. No queremos un try-catch, queremos que el programador corrija esa llamada.

Ejemplo completo: el cajero automático

Vamos a implementar el caso del banco usando una excepción verificada (Checked), porque queremos gestionarla.

Paso 1: La Excepción Podemos añadirle atributos extra para dar más información (ej: cuánto dinero falta).

public class SaldoInsuficienteException extends Exception {
    private double cantidadFaltante;

    public SaldoInsuficienteException(String mensaje, double falta) {
        super(mensaje);
        this.cantidadFaltante = falta;
    }

    public double getCantidadFaltante() {
        return cantidadFaltante;
    }
}
Copied!

Paso 2: La Clase de Negocio

public class CuentaBancaria {
    private double saldo = 100.0;

    // AVISAMOS con 'throws' que este método puede fallar
    public void retirar(double cantidad) throws SaldoInsuficienteException {
        if (cantidad > saldo) {
            double falta = cantidad - saldo;
            // LANZAMOS el error
            throw new SaldoInsuficienteException("No hay tanta pasta", falta);
        }
        saldo -= cantidad;
        System.out.println("Retirada exitosa. Quedan: " + saldo);
    }
}
Copied!

Paso 3: El Uso (Gestión)

public static void main(String[] args) {
    CuentaBancaria cuenta = new CuentaBancaria();

    try {
        cuenta.retirar(500.0); // Esto fallará
    } catch (SaldoInsuficienteException e) {
        // Gestionamos el error de negocio elegantemente
        System.out.println("Error: " + e.getMessage());
        System.out.println("Te faltan: " + e.getCantidadFaltante() + " euros.");
    }
}
Copied!