ApexSensei

Drills › Debug it

Stop a trigger calling itself

Debug it · Advanced · 15 min · Runs in your Salesforce Developer org · Apex Path

Scenario. Since a new handler went live, agents cannot close a Case. The error says maximum trigger depth exceeded, and nobody has changed the trigger.

Closing one Case now fails with maximum trigger depth exceeded. The after-update handler updates the Case, which runs the handler again. Break the loop.

What you will learn

maximum trigger depth exceeded means a trigger caused DML that ran the same trigger, again and again, sixteen times. Here the after-update handler updates the Case it was called for, so the update runs it again.

Two fixes work. A static Set remembers the Ids handled in this transaction:

private static Set<Id> handledIds = new Set<Id>();

Or act only when Status changed to Closed, using oldMap.

Gotcha. A static Boolean also blocks every later record. Track Ids.

The task

Fix the handler so each Case closed in a transaction is marked exactly once, and the follow-up update does not run the handler's work again.

Examples:

  • Case Status New → Closed: Description becomes Closed by the handler
  • Case Status New → Working: Description stays as it was
  • 200 Cases closed together → each marked once, with one follow-up update

Requirements:

  1. Only act on Cases whose Status is Closed.
  2. Stop the second run. Either skip Ids already in a static Set<Id>, or skip Cases whose old Status in oldMap was already Closed.
  3. Keep one follow-up update for the whole list, after the loop.
  4. Do not change the marker text.

Starter code

public class AS_AFE55B6263D0_CaseCloser {
    public static void afterUpdate(List<Case> cases, Map<Id, Case> oldMap) {
        List<Case> followUps = new List<Case>();
        for (Case caseRecord : cases) {
            if (caseRecord.Status == 'Closed') {
                followUps.add(new Case(
                    Id = caseRecord.Id,
                    Description = 'Closed by the handler'
                ));
            }
        }
        if (!followUps.isEmpty()) {
            update followUps;
        }
    }
}

When it passes

Closing a Case marks it once and never loops. Other Status changes do nothing. 200 Cases closed together cost the same DML as one.

Try this drill free

You write the Apex yourself. ApexSensei runs it and tells you what passed and what did not.

‹ Fix a test that checks nothing · Fix a mixed DML error ›