Exception Handling Integration
Part of the Object Oriented Programming section of Coddy's Java journey — lesson 82 of 87.
Challenge
EasyLet'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 calledLibraryExceptionthat extendsException. 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 extendsLibraryException. 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 likeBook not available: [isbn].Library.java: Update your Library class to throw exceptions instead of printing error messages. Modify theborrowBook(String userId, String isbn)method to:- Throw
LibraryExceptionwith messageUser not found: [userId]if the user doesn't exist - Throw
LibraryExceptionwith messageBook not found: [isbn]if the book doesn't exist - Throw
BookNotAvailableExceptionif 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 LibraryExceptionand change the return type toString.Keep all other methods (addBook, registerUser, findBookByIsbn, findUserById, returnBook, removeBook, searchByTitle, searchByAuthor, getAvailableBooks) working as before.
- Throw
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:authorREGISTER_USER:id:nameBORROW:userId:isbn
Process each command. For ADD_BOOK, print
Added: [title]. For REGISTER_USER, printRegistered: [name]. For BORROW commands, use a try-catch block to handle exceptions—on success print the confirmation message, on anyLibraryExceptionprintError: [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 completedNotice 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
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe this KeywordMethodsFields (Attributes)Constructor MethodConstructor OverloadingRecap - Simple Calculator4Inheritance
Basic Inheritance (extends)The super KeywordMethod Overriding (@Override)Constructor ChainingThe Object ClassSingle & Multilevel InheritWhy No Multi Class InheritRecap - Employee Hierarchy7Special Methods & Object Class
toString() Methodequals() and hashCode()clone() MethodcompareTo() and ComparableComparator InterfaceRecap - Custom Sorting10Exception Handling in OOP
Exception Class HierarchyCustom ExceptionsChecked vs Unchecked ErrorsTry With Resources PatternRecap - Validated User13Project: Library Management
Project Overview & UML DesignBook and User Classes2Access Modifiers & Encapsulate
Access Levels OverviewGetter and Setter MethodsInformation HidingThe final KeywordRecap - Bank Account Manager5Polymorphism
Method Overloading BasicsMethod Overriding (Run-Time)Upcasting and DowncastingThe instanceof OperatorAbstract Classes and MethodsRecap - Shape Calculator8Advanced OOP Concepts
Composition vs InheritanceAggregation vs CompositionInner Nested & Anonymous ClassEnums and Enum MethodsRecords (Java 16+)Sealed Classes (Java 17+)3Class Props & Static Member
Instance vs Static VariablesStatic MethodsStatic BlocksConstants (static final)Recap - Counter & Utility6Interfaces & Abstract Classes
Introduction to InterfacesImplementing InterfacesMulti Interface ImplemenDefault & Static in InterfaceAbstract Classes vs InterfacesFunctional InterfacesRecap - Payment System