Menu
Coddy logo textTech

Integración de manejo de excepciones

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy — lección 82 de 87.

challenge icon

Desafío

Fácil

¡Hagamos que tu Sistema de Gestión de Biblioteca sea más robusto integrando un manejo de excepciones adecuado! Un sistema de biblioteca real necesita manejar con elegancia las condiciones de error: ¿qué sucede cuando alguien intenta pedir prestado un libro que no existe, o cuando un usuario intenta pedir prestados más libros de los permitidos? Crearás excepciones personalizadas que proporcionen comentarios significativos para estos escenarios.

Continuarás construyendo sobre tu código existente a través de seis archivos:

  • Book.java: Mantén tu clase Book con toda la funcionalidad existente: isbn, title, author, isAvailable, borrowedBy, getDetails() y los getters/setters apropiados.
  • User.java: Mantén tu clase User con id, name, el ArrayList borrowedBooks, borrowBook(), returnBook(), getBorrowedCount() y toString().
  • LibraryException.java: Crea una clase de excepción personalizada base llamada LibraryException que extienda de Exception. Esta será la clase padre para todas las excepciones específicas de la biblioteca. Incluye un constructor que acepte un mensaje y lo pase a la clase padre.
  • BookNotAvailableException.java: Crea una excepción personalizada que extienda de LibraryException. Esta excepción debe lanzarse cuando alguien intenta pedir prestado un libro que ya está prestado. Incluye un constructor que acepte el ISBN del libro y cree un mensaje significativo como "Book not available: " + isbn.
  • Library.java: Actualiza tu clase Library para lanzar excepciones en lugar de imprimir mensajes de error. Modifica el método borrowBook(String userId, String isbn) para:
    • Lanzar LibraryException con el mensaje "User not found: " + userId si el usuario no existe
    • Lanzar LibraryException con el mensaje "Book not found: " + isbn si el libro no existe
    • Lanzar BookNotAvailableException si el libro ya está prestado
    • En caso de éxito, haz que el usuario pida prestado el libro y devuelva el mensaje de confirmación userName + " borrowed " + bookTitle

    Cambia la firma del método a throws LibraryException y cambia el tipo de retorno a String.

    Mantén todos los demás métodos (addBook, registerUser, findBookByIsbn, findUserById, returnBook, removeBook, searchByTitle, searchByAuthor, getAvailableBooks) funcionando como antes.

  • Main.java: ¡Demuestra tu manejo de excepciones! Recibirás una cadena de comandos separados por comas. Cada comando sigue uno de estos formatos:
    • ADD_BOOK:isbn:title:author
    • REGISTER_USER:id:name
    • BORROW:userId:isbn

    Procesa cada comando. Para ADD_BOOK, imprime "Added: " + title. Para REGISTER_USER, imprime "Registered: " + name. Para los comandos BORROW, usa un bloque try-catch para manejar las excepciones; en caso de éxito, imprime el mensaje de confirmación, ante cualquier LibraryException imprime "Error: " + e.getMessage().

    Después de procesar todos los comandos, imprime "Operations completed".

Recibirás una entrada: una cadena de comandos separados por comas.

Por ejemplo, con la entrada ADD_BOOK:ISBN-001:Clean Code:Robert Martin,REGISTER_USER:U001:Alice,BORROW:U001:ISBN-001,BORROW:U001:ISBN-001,BORROW:U002:ISBN-001, tu salida sería:

Added: Clean Code
Registered: Alice
Alice borrowed Clean Code
Error: Book not available: ISBN-001
Error: User not found: U002
Operations completed

Observa cómo las excepciones personalizadas proporcionan mensajes de error claros y específicos. El primer préstamo tiene éxito, el segundo falla porque el libro ya está prestado (BookNotAvailableException) y el tercero falla porque el usuario U002 no existe (LibraryException). ¡Este enfoque hace que tu sistema de biblioteca sea mucho más informativo y fácil de depurar que los mensajes de error genéricos!

Pruébalo tú mismo

import java.util.Scanner;
import java.util.ArrayList;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leer los comandos separados por comas
        String input = scanner.nextLine();
        String[] commands = input.split(",");
        
        // Crear Library y AdminService
        Library library = new Library();
        AdminService adminService = new AdminService(library);
        
        // Procesar cada comando
        for (String command : commands) {
            String[] parts = command.split(":");
            String operation = parts[0];
            
            if (operation.equals("ADD_BOOK")) {
                String isbn = parts[1];
                String title = parts[2];
                String author = parts[3];
                if (adminService.addBook(isbn, title, author)) {
                    System.out.println("Added: " + title);
                }
            } else if (operation.equals("REMOVE_BOOK")) {
                String isbn = parts[1];
                if (adminService.removeBook(isbn)) {
                    System.out.println("Removed: " + isbn);
                } else {
                    System.out.println("Cannot remove: " + isbn);
                }
            } else if (operation.equals("REGISTER_USER")) {
                String id = parts[1];
                String name = parts[2];
                if (adminService.registerUser(id, name)) {
                    System.out.println("Registered: " + name);
                }
            } else if (operation.equals("BORROW")) {
                String userId = parts[1];
                String isbn = parts[2];
                // TODO: Usar un bloque try-catch para llamar a library.borrowBook(userId, isbn)
                // En caso de éxito, imprimir el mensaje de confirmación devuelto
                // En caso de LibraryException, imprimir "Error: " + e.getMessage()
            }
        }
        
        // TODO: Imprimir "Operations completed"
    }
}

Todas las lecciones de Programación Orientada a Objetos