Menu
Coddy logo textTech

Try, Catch, Finally

Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy. Lección 68 de 91.

Ahora que sabes cómo crear y lanzar excepciones, necesitas aprender a capturarlas. La estructura try-catch-finally te permite manejar las excepciones correctamente en lugar de dejar que bloqueen tu aplicación.

Envuelve el código que podría lanzar una excepción en un bloque try y después gestiona la excepción en un bloque catch:

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

$calc = new Calculator();

try {
    echo $calc->divide(10, 0);
} catch (InvalidArgumentException $e) {
    echo "Error: " . $e->getMessage();
}

Salida:

Error: Cannot divide by zero

Puedes capturar distintos tipos de excepciones con varios bloques catch. PHP los comprueba en orden, así que coloca primero las excepciones más específicas:

<?php
try {
    // código riesgoso
} catch (InvalidArgumentException $e) {
    echo "Bad input: " . $e->getMessage();
} catch (Exception $e) {
    echo "Something went wrong: " . $e->getMessage();
}

El bloque finally se ejecuta independientemente de si se lanzó o capturó una excepción. Es perfecto para tareas de limpieza, como cerrar conexiones:

<?php
try {
    echo "Attempting operation\n";
    throw new Exception("Failed");
} catch (Exception $e) {
    echo "Caught: " . $e->getMessage() . "\n";
} finally {
    echo "Cleanup complete";
}

Salida:

Attempting operation
Caught: Failed
Cleanup complete

El bloque finally se ejecuta incluso si devuelves el control desde dentro de los bloques try o catch, lo que lo hace confiable para las operaciones esenciales de limpieza.

challenge icon

Desafío

Fácil

Construyamos un sistema de procesamiento de archivos que demuestre cómo try-catch-finally funciona conjuntamente para gestionar los errores correctamente y garantizar que la limpieza siempre se realice.

Organizarás tu código en tres archivos:

  • FileException.php: Crea una clase personalizada FileException que extienda Exception. Esta representará los errores relacionados con archivos en tu sistema.
  • FileProcessor.php: Crea una clase FileProcessor que simule operaciones con archivos. Incluye el archivo FileException. Tu clase debe tener:
    • Una propiedad booleana privada $isOpen inicializada en false
    • Un método open(string $filename): void que establezca $isOpen en true e imprima "Opening: [filename]". Si el nombre de archivo es "invalid.txt", lanza una FileException con el mensaje "Cannot open file"
    • Un método process(): void que imprima "Processing file...". Si $isOpen es false, lanza una RuntimeException con el mensaje "File not open"
    • Un método close(): void que establezca $isOpen en false e imprima "File closed"
    • Un método isOpen(): bool que devuelva el estado actual
  • main.php: Incluye el archivo FileProcessor. Recibirás una entrada: un nombre de archivo.

    Crea un FileProcessor y utiliza una estructura try-catch-finally para:

    • En el bloque try: llama a open() con el nombre de archivo y después llama a process()
    • Captura primero FileException e imprime "File error: [message]"
    • Captura RuntimeException e imprime "Runtime error: [message]"
    • En el bloque finally: comprueba si el archivo está abierto mediante isOpen() y, si lo está, llama a close(). Después, imprime "Cleanup complete"

El bloque finally garantiza que la limpieza se realice tanto si las operaciones tienen éxito como si fallan. Este patrón es esencial para gestionar recursos como archivos, conexiones de bases de datos o sockets de red, cuya limpieza debe realizarse independientemente de lo que ocurra durante el procesamiento.

Pruébalo tú mismo

<?php
require_once 'FileProcessor.php';

// Leer entrada
$filename = trim(fgets(STDIN));

// TODO: Crea una instancia de FileProcessor

// TODO: Usa la estructura try-catch-finally:
// - En el bloque try: llama a open() con el filename, luego llama a process()
// - Captura FileException primero e imprime "File error: [message]"
// - Captura RuntimeException e imprime "Runtime error: [message]"
// - En el bloque finally: comprueba si el archivo está abierto usando isOpen(), si es así llama a close()
//   Then print "Cleanup complete"

?>
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

Practica por tu cuenta: Compilador de PHP online