Menu
Coddy logo textTech

Exception Handling Integration

Part of the Object Oriented Programming section of Coddy's Java journey — lesson 82 of 87.

challenge icon

Challenge

Easy

Let's make your Library Management System more robust by integrating proper exception handling! A real library system needs to gracefully handle error conditions—what happens when someone tries to borrow a book that doesn't exist, or when a user attempts to borrow more books than allowed? You'll create custom exceptions that provide meaningful feedback for these scenarios.

You'll continue building on your existing code across six files:

  • Book.java: Keep your Book class with all existing functionality—isbn, title, author, isAvailable, borrowedBy, getDetails(), and the appropriate getters/setters.
  • User.java: Keep your User class with id, name, the borrowedBooks ArrayList, borrowBook(), returnBook(), getBorrowedCount(), and toString().
  • LibraryException.java: Create a base custom exception class called LibraryException that extends Exception. This will be the parent class for all library-specific exceptions. Include a constructor that accepts a message and passes it to the parent class.
  • BookNotAvailableException.java: Create a custom exception that extends LibraryException. This exception should be thrown when someone tries to borrow a book that is already borrowed. Include a constructor that accepts the book's ISBN and creates a meaningful message like Book not available: [isbn].
  • Library.java: Update your Library class to throw exceptions instead of printing error messages. Modify the borrowBook(String userId, String isbn) method to:
    • Throw LibraryException with message User not found: [userId] if the user doesn't exist
    • Throw LibraryException with message Book not found: [isbn] if the book doesn't exist
    • Throw BookNotAvailableException if the book is already borrowed
    • On success, have the user borrow the book and return the confirmation message [userName] borrowed [bookTitle]

    Change the method signature to throws LibraryException and change the return type to String.

    Keep all other methods (addBook, registerUser, findBookByIsbn, findUserById, returnBook, removeBook, searchByTitle, searchByAuthor, getAvailableBooks) working as before.

  • Main.java: Demonstrate your exception handling! You'll receive a comma-separated string of commands. Each command follows one of these formats:
    • ADD_BOOK:isbn:title:author
    • REGISTER_USER:id:name
    • BORROW:userId:isbn

    Process each command. For ADD_BOOK, print Added: [title]. For REGISTER_USER, print Registered: [name]. For BORROW commands, use a try-catch block to handle exceptions—on success print the confirmation message, on any LibraryException print Error: [exception message].

    After processing all commands, print Operations completed.

You will receive one input: a comma-separated string of commands.

For example, with input ADD_BOOK:ISBN-001:Clean Code:Robert Martin,REGISTER_USER:U001:Alice,BORROW:U001:ISBN-001,BORROW:U001:ISBN-001,BORROW:U002:ISBN-001, your output would be:

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

Notice how the custom exceptions provide clear, specific error messages. The first borrow succeeds, the second fails because the book is already borrowed (BookNotAvailableException), and the third fails because user U002 doesn't exist (LibraryException). This approach makes your library system much more informative and easier to debug than generic error messages!

Try it yourself

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

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Read the comma-separated commands
        String input = scanner.nextLine();
        String[] commands = input.split(",");
        
        // Create Library and AdminService
        Library library = new Library();
        AdminService adminService = new AdminService(library);
        
        // Process each command
        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: Use a try-catch block to call library.borrowBook(userId, isbn)
                // On success, print the returned confirmation message
                // On LibraryException, print "Error: " + e.getMessage()
            }
        }
        
        // TODO: Print "Operations completed"
    }
}

All lessons in Object Oriented Programming