Intermediate 25 min read

Handle Errors

By the end of this lesson, you'll be able to:

  • Reject checking out a book that's already checked out
  • Reject returning a book via a checkout that's already closed
  • Use a custom exception for a genuinely invalid library operation

Prerequisites: "Search the Library"

A custom exception for library errors

public class LibraryException extends Exception {}
  1. public class LibraryException extends Exception {} — exactly Module 13's custom exception pattern — a one-line class that lets library-specific failures be caught and handled distinctly from generic Apex exceptions.

Guarding against checking out an already-borrowed book

public Checkout__c checkOutBook(Id bookId, String memberName) {
    Book__c book = [SELECT Id, Is_Checked_Out__c FROM Book__c WHERE Id = :bookId];

    if (book.Is_Checked_Out__c) {
        throw new LibraryException('This book is already checked out.');
    }

    book.Is_Checked_Out__c = true;
    update book;

    Checkout__c checkout = new Checkout__c(Book__c = bookId, Member_Name__c = memberName, Checkout_Date__c = Date.today());
    insert checkout;
    return checkout;
}
  1. public Checkout__c checkOutBook(Id bookId, String memberName) { — the method.
  2. Book__c book = [SELECT Id, Is_Checked_Out__c FROM Book__c WHERE Id = :bookId]; — queries the book first.
  3. (blank line)
  4. if (book.Is_Checked_Out__c) { — checking this before doing anything else prevents exactly the "two members borrow the same physical book" scenario the previous lesson flagged as the reason Book__c and Checkout__c must stay in sync.
  5. throw new LibraryException('This book is already checked out.'); — rejects with a clear, named failure.
  6. } — closes the if.
  7. (blank line)
  8. book.Is_Checked_Out__c = true; — only reached if the guard passed.
  9. update book; — saves the change.
  10. (blank line)
  11. Checkout__c checkout = new Checkout__c(Book__c = bookId, Member_Name__c = memberName, Checkout_Date__c = Date.today()); — builds the checkout record.
  12. insert checkout; — saves it.
  13. return checkout; — hands it back.
  14. } — closes the method.

Guarding against returning an already-closed checkout

public void returnBook(Id checkoutId) {
    Checkout__c checkout = [SELECT Id, Book__c, Return_Date__c FROM Checkout__c WHERE Id = :checkoutId];

    if (checkout.Return_Date__c != null) {
        throw new LibraryException('This checkout has already been returned.');
    }

    checkout.Return_Date__c = Date.today();
    update checkout;

    Book__c book = [SELECT Id FROM Book__c WHERE Id = :checkout.Book__c];
    book.Is_Checked_Out__c = false;
    update book;
}
  1. public void returnBook(Id checkoutId) { — the method.
  2. Checkout__c checkout = [SELECT Id, Book__c, Return_Date__c FROM Checkout__c WHERE Id = :checkoutId]; — queries the checkout, including Return_Date__c.
  3. (blank line)
  4. if (checkout.Return_Date__c != null) { — a Checkout__c with a Return_Date__c already set means that borrowing event is closed.
  5. throw new LibraryException('This checkout has already been returned.'); — a genuine misuse, worth a clear LibraryException rather than silently double-processing the return.
  6. } — closes the if.
  7. (blank line)
  8. checkout.Return_Date__c = Date.today(); — only reached if the guard passed.
  9. update checkout; — saves the change.
  10. (blank line)
  11. Book__c book = [SELECT Id FROM Book__c WHERE Id = :checkout.Book__c]; — queries the related book.
  12. book.Is_Checked_Out__c = false; — marks it available again.
  13. update book; — saves the change.
  14. } — closes the method.

Exercise

Given a Book__c queried with Is_Checked_Out__c, write a guard that throws LibraryException("This book is already checked out.") if it's already checked out.

Show hint

if (book.Is_Checked_Out__c) { throw new LibraryException(...); }

Salesforce: ○ Not connected Connect
APEX

Execution Results

Run your code to see the result.

Handle Errors Quiz

1. What does checking Return_Date__c != null before returning a book prevent?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

Real library operations can fail in predictable ways — this lesson guards checkOutBook and returnBook against the two most obvious misuses, using a custom exception from Module 13.