Beginner 25 min read

Handle Errors Gracefully

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

  • Distinguish between an expected business rejection and a genuine programming error
  • Guard against a null Student being passed to enroll
  • Choose a return-value approach vs an exception for different kinds of failure

Prerequisites: "Add Business Rules"

Guarding against null input

public Boolean enroll(Student student) {
    if (student == null) {
        System.debug('Cannot enroll a null student.');
        return false;
    }

    for (Student existing : enrolledStudents) {
        if (existing.getStudentId() == student.getStudentId()) {
            return false;
        }
    }

    if (enrolledStudents.size() >= maxSize) {
        return false;
    }

    enrolledStudents.add(student);
    return true;
}
  1. public Boolean enroll(Student student) { — the method, now with a null guard added first.
  2. if (student == null) { — checks for null before anything else touches student.
  3. System.debug('Cannot enroll a null student.'); — a clear reason logged.
  4. return false; — rejects cleanly.
  5. } — closes the if.
  6. (blank line)
  7. for (Student existing : enrolledStudents) { — the duplicate check, unchanged from the previous lesson.
  8. if (existing.getStudentId() == student.getStudentId()) { — safe now, since student is guaranteed non-null by this point.
  9. return false; — rejects the duplicate.
  10. } — closes the if.
  11. } — closes the loop.
  12. (blank line)
  13. if (enrolledStudents.size() >= maxSize) { — the capacity check, also unchanged.
  14. return false; — rejects for capacity.
  15. } — closes the if.
  16. (blank line)
  17. enrolledStudents.add(student); — only reached if every check passed.
  18. return true; — reports success.
  19. } — closes the method.

Warning: Without the null check on line 2, student.getStudentId() inside the loop (line 8) would throw a NullPointerException the moment someone accidentally passes null — a crash for what should be a simple, handleable rejection. Checking student == null first turns a crash into a clean "no."

Two different kinds of failure

  • Expected business outcomes (roster full, already enrolled, null input) — these are normal things that happen in real usage. Returning false and debugging a clear reason is enough; the caller can check the result and react.
  • Genuine programming errors — like a CourseRoster created with a negative maxSize, which should never happen if the rest of the code is correct — are better suited to throwing an exception (covered in a later module), since they signal a bug rather than a normal outcome.

A real business example: Registrar's Office

CourseRoster apexBasics = new CourseRoster('Apex Basics', 2);

Student alice = new Student('S001', 'Alice Nkosi', 'alice@example.com');
Student ben = new Student('S002', 'Ben Dlamini', 'ben@example.com');
Student carla = new Student('S003', 'Carla Botha', 'carla@example.com');

apexBasics.enroll(alice); // true
apexBasics.enroll(ben);   // true
apexBasics.enroll(carla); // false — roster full, handled cleanly, no crash
  1. CourseRoster apexBasics = new CourseRoster('Apex Basics', 2); — a roster capped at 2 seats.
  2. (blank line)
  3. Student alice = new Student('S001', 'Alice Nkosi', 'alice@example.com'); — a student.
  4. Student ben = new Student('S002', 'Ben Dlamini', 'ben@example.com'); — a second student.
  5. Student carla = new Student('S003', 'Carla Botha', 'carla@example.com'); — a third student.
  6. (blank line)
  7. apexBasics.enroll(alice); // true — seat 1 of 2.
  8. apexBasics.enroll(ben); // true — seat 2 of 2.
  9. apexBasics.enroll(carla); // false — roster full, handled cleanly, no crash.

A real registrar's system processes hundreds of enrollment attempts, many of which fail for ordinary reasons like a full class. Graceful handling means the whole batch keeps running instead of one rejected enrollment crashing the entire process.

Exercise

Add a null check to a method addCourse(Course course) on a hypothetical Student class, debugging "Cannot add a null course." and returning false when course is null.

Show hint

if (course == null) { ...; return false; }

Salesforce: ○ Not connected Connect
APEX

Execution Results

Run your code to see the result.

Handle Errors Gracefully Quiz

1. What happens if student.getStudentId() runs on a null student with no guard in place?

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

Not every failure is the same kind of problem — a full roster is an expected business outcome, but a null Student passed in is a programming mistake, and each deserves a different kind of handling.