Intermediate 25 min read

Custom Exceptions

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

  • Write a custom exception class extending Exception
  • Throw a custom exception with a meaningful message
  • Explain why a custom exception communicates intent better than a generic one

Prerequisites: "Common Built-In Exceptions"

Defining a custom exception

public class RosterFullException extends Exception {}
  1. public class RosterFullException extends Exception {} — any class that extends Exception becomes throwable — this one-liner is often all a custom exception needs. Apex's built-in Exception class already provides getMessage(), getStackTraceString(), and everything else needed to work like any other exception.

Throwing and catching it

public class RosterFullException extends Exception {}

public void enroll(Student student) {
    if (enrolledStudents.size() >= maxSize) {
        throw new RosterFullException('Cannot enroll ' + student.getName() + ' — roster is full.');
    }
    enrolledStudents.add(student);
}

try {
    courseRoster.enroll(newStudent);
} catch (RosterFullException e) {
    System.debug(e.getMessage());
}
  1. public class RosterFullException extends Exception {} — the custom exception, unchanged.
  2. (blank line)
  3. public void enroll(Student student) { — a method that might reject an enrollment.
  4. if (enrolledStudents.size() >= maxSize) { — checks the business rule.
  5. throw new RosterFullException('Cannot enroll ' + student.getName() + ' — roster is full.'); — throw raises the exception immediately, stopping normal execution and jumping straight to a matching catch.
  6. } — closes the if.
  7. enrolledStudents.add(student); — only reached if the exception wasn't thrown.
  8. } — closes the method.
  9. (blank line)
  10. try { — wraps the call that might throw.
  11. courseRoster.enroll(newStudent); — the call.
  12. } catch (RosterFullException e) { — catches the specific, named failure.
  13. System.debug(e.getMessage()); — logs the message passed to throw.
  14. } — closes the catch.

This works the same way a built-in exception like MathException would, but now naming a business-specific failure instead of a generic language-level one.

Why bother with a custom exception at all?

Module 12's enroll() method returned false on failure instead of throwing — a perfectly valid choice for an expected outcome. A custom exception fits better when a failure is exceptional enough that it should interrupt the normal flow and be handled distinctly. Compare:

catch (Exception e) {
    // Could be ANY problem — a typo, a null field, a real business rule.
}

catch (RosterFullException e) {
    // Unambiguous: this specific business rule was violated.
}
  1. catch (Exception e) { — a generic catch could be any problem — a typo, a null field, a real business rule.
  2. // Could be ANY problem — a typo, a null field, a real business rule. — spells out the ambiguity.
  3. } — closes the generic catch.
  4. (blank line)
  5. catch (RosterFullException e) { — a named exception type is unambiguous: this specific business rule was violated.
  6. // Unambiguous: this specific business rule was violated. — spells out the clarity.
  7. } — closes the specific catch.

A named exception type turns "something went wrong" into "specifically, the roster was full" — both for a human reading the catch block and for code that wants to react differently to different named failures.

Exercise

Write a custom exception class InvalidDiscountException, and a method applyDiscount(Decimal percent) that throws it with a message if percent is negative or over 100.

Show hint

public class InvalidDiscountException extends Exception {}

Salesforce: ○ Not connected Connect
APEX

Execution Results

Run your code to see the result.

Custom Exceptions Quiz

1. What must a custom exception class do to be throwable?

2. A custom exception can only be caught with a generic catch (Exception e) block.

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

A custom exception lets your own code signal a specific, named business failure — far clearer to a future reader (or a catch block) than a generic error.