Menu
Coddy logo textTech

Clases de excepción

Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy — lección 66 de 91.

En PHP, las excepciones son objetos utilizados para señalar que algo salió mal durante la ejecución. La clase base para todas las excepciones es Exception, y comprender su estructura te ayuda a manejar errores de manera efectiva en tus aplicaciones de POO.

Cuando lanzas una excepción, creas una instancia de la clase Exception (o una subclase) con un mensaje que describe qué salió mal:

<?php
class BankAccount {
    public function __construct(private float $balance = 0) {}
    
    public function withdraw(float $amount): float {
        if ($amount > $this->balance) {
            throw new Exception("Insufficient funds");
        }
        $this->balance -= $amount;
        return $amount;
    }
}

$account = new BankAccount(100);
$account->withdraw(150);

Esto produciría un error de excepción no capturada con el mensaje "Insufficient funds".

PHP proporciona varias clases de excepción integradas para diferentes situaciones. InvalidArgumentException señala una entrada incorrecta, RuntimeException indica errores durante la ejecución, y LogicException representa errores de programación:

<?php
class Calculator {
    public function divide(int $a, int $b): float {
        if ($b === 0) {
            throw new InvalidArgumentException("Cannot divide by zero");
        }
        return $a / $b;
    }
}

Cada objeto de excepción contiene información útil: getMessage() devuelve el mensaje de error, getCode() devuelve un código de error opcional, getFile() y getLine() indican dónde se lanzó la excepción. El uso de tipos de excepción específicos hace que la intención de su código sea más clara y permite un manejo de errores más preciso.

challenge icon

Desafío

Fácil

Vamos a construir un sistema de gestión de inventario que utiliza las clases de excepción integradas de PHP para señalar diferentes tipos de problemas. Crearás un inventario de productos donde las operaciones pueden fallar de maneras específicas y significativas.

Organizarás tu código en tres archivos:

  • Product.php — Crea una clase Product que represente un artículo en el inventario. Usa la promoción de constructor para un $sku (string) público, un $name (string) público y un $quantity (int) privado. Tu clase debe tener:
    • Un método getQuantity(): int que devuelva la cantidad actual
    • Un método addStock(int $amount): void que aumente la cantidad. Si la cantidad es menor que 1, lanza una InvalidArgumentException con el mensaje "Amount must be positive"
    • Un método removeStock(int $amount): void que disminuya la cantidad. Si la cantidad es menor que 1, lanza una InvalidArgumentException con el mensaje "Amount must be positive". Si la cantidad excede la cantidad actual, lanza una RuntimeException con el mensaje "Insufficient stock"
  • Inventory.php — Crea una clase Inventory que gestione una colección de productos. Incluye el archivo Product. Tu clase debe tener:
    • Un array privado para almacenar productos indexados por SKU
    • Un método addProduct(Product $product): void que añada un producto. Si ya existe un producto con el mismo SKU, lanza una LogicException con el mensaje "Product already exists: [sku]"
    • Un método getProduct(string $sku): Product que devuelva un producto por SKU. Si no se encuentra, lanza una InvalidArgumentException con el mensaje "Product not found: [sku]"
  • main.php — Incluye el archivo Inventory. Recibirás tres entradas: un SKU, un nombre de producto y una operación ("add", "remove", o "duplicate").

    Crea un Inventory y añade un nuevo Product con el SKU dado, el nombre y una cantidad inicial de 10.

    Basado en la operación:

    • "add": Llama a addStock(5) en el producto, luego imprime "Stock updated: [quantity]"
    • "remove": Llama a removeStock(15) en el producto (esto debería lanzar una excepción)
    • "duplicate": Intenta añadir otro producto con el mismo SKU (esto debería lanzar una excepción)

    Cuando se lance una excepción, imprime el nombre de la clase de la excepción seguido de ": " y el mensaje de la excepción. Usa la función get_class() de PHP para obtener el nombre de la clase.

Este desafío demuestra cómo diferentes tipos de excepciones comunican diferentes tipos de problemas — entradas inválidas, fallos en tiempo de ejecución y errores de lógica — haciendo que el manejo de errores de tu código sea más preciso y significativo.

Hoja de referencia

En PHP, las excepciones son objetos que señalan errores durante la ejecución. La clase base es Exception.

Para lanzar una excepción, cree una instancia con un mensaje descriptivo:

<?php
class BankAccount {
    public function __construct(private float $balance = 0) {}
    
    public function withdraw(float $amount): float {
        if ($amount > $this->balance) {
            throw new Exception("Insufficient funds");
        }
        $this->balance -= $amount;
        return $amount;
    }
}

PHP proporciona clases de excepción integradas para diferentes situaciones:

  • InvalidArgumentException — señala una entrada no válida
  • RuntimeException — indica errores durante la ejecución
  • LogicException — representa errores de programación
<?php
class Calculator {
    public function divide(int $a, int $b): float {
        if ($b === 0) {
            throw new InvalidArgumentException("Cannot divide by zero");
        }
        return $a / $b;
    }
}

Los objetos de excepción proporcionan métodos útiles:

  • getMessage() — devuelve el mensaje de error
  • getCode() — devuelve un código de error opcional
  • getFile() — devuelve el archivo donde se lanzó la excepción
  • getLine() — devuelve el número de línea donde se lanzó la excepción

Use get_class() para recuperar el nombre de la clase de un objeto de excepción.

Pruébalo tú mismo

<?php

require_once 'Inventory.php';

// Leer entradas
$sku = trim(fgets(STDIN));
$name = trim(fgets(STDIN));
$operation = trim(fgets(STDIN));

try {
    // TODO: Crear un Inventario
    // TODO: Crear un Producto con el SKU, nombre y cantidad inicial de 10 dados
    // TODO: Agregar el producto al inventario
    
    // TODO: Basado en la operación:
    // - "add": Llamar a addStock(5) en el producto, luego imprimir "Stock updated: [quantity]"
    // - "remove": Llamar a removeStock(15) en el producto
    // - "duplicate": Intentar agregar otro producto con el mismo SKU
    
} catch (Exception $e) {
    // TODO: Imprimir el nombre de la clase de la excepción seguido de ": " y el mensaje
    // Sugerencia: Usar get_class($e) para obtener el nombre de la clase
}

?>
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos