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 {}
public class RosterFullException extends Exception {}— any class thatextends Exceptionbecomes throwable — this one-liner is often all a custom exception needs. Apex's built-inExceptionclass already providesgetMessage(),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());
}
public class RosterFullException extends Exception {}— the custom exception, unchanged.- (blank line)
public void enroll(Student student) {— a method that might reject an enrollment.if (enrolledStudents.size() >= maxSize) {— checks the business rule.throw new RosterFullException('Cannot enroll ' + student.getName() + ' — roster is full.');—throwraises the exception immediately, stopping normal execution and jumping straight to a matchingcatch.}— closes theif.enrolledStudents.add(student);— only reached if the exception wasn't thrown.}— closes the method.- (blank line)
try {— wraps the call that might throw.courseRoster.enroll(newStudent);— the call.} catch (RosterFullException e) {— catches the specific, named failure.System.debug(e.getMessage());— logs the message passed tothrow.}— closes thecatch.
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.
}
catch (Exception e) {— a generic catch could be any problem — a typo, a null field, a real business rule.// Could be ANY problem — a typo, a null field, a real business rule.— spells out the ambiguity.}— closes the generic catch.- (blank line)
catch (RosterFullException e) {— a named exception type is unambiguous: this specific business rule was violated.// Unambiguous: this specific business rule was violated.— spells out the clarity.}— 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 {}
Custom Exceptions Quiz
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.