Handle Errors Gracefully
By the end of this lesson, you'll be able to:
- Guard against a Case with a null Priority or Type
- Ensure a malformed routing rule doesn't crash the entire trigger
- Distinguish a data problem in one Case from a genuine bug in the routing logic
Prerequisites: "Secure Data Access"
Guarding against a null Priority or Type
for (Case c : newCases) {
if (c.Priority == null || c.Type == null) {
c.Assigned_Queue__c = DEFAULT_QUEUE;
continue;
}
String key = c.Priority + '|' + c.Type;
// ... rest of the matching logic ...
}
Without this check, c.Priority + '|' + c.Type on a Case with a null Priority would still technically work (Apex's + operator handles null in String concatenation gracefully), but the resulting key would never match any real rule — this explicit guard makes the intent clear and routes straight to the fallback, using Module 7's continue to skip the rest of that iteration.
A malformed custom metadata rule shouldn't crash everything
private Map<String, String> buildRoutingLookup() {
List<Case_Routing_Rule__mdt> rules = [SELECT Priority__c, Case_Type__c, Queue_Name__c FROM Case_Routing_Rule__mdt];
Map<String, String> lookup = new Map<String, String>();
for (Case_Routing_Rule__mdt rule : rules) {
if (String.isBlank(rule.Priority__c) || String.isBlank(rule.Case_Type__c) || String.isBlank(rule.Queue_Name__c)) {
System.debug('Skipping incomplete routing rule: ' + rule.Id);
continue;
}
lookup.put(rule.Priority__c + '|' + rule.Case_Type__c, rule.Queue_Name__c);
}
return lookup;
}
A support manager could accidentally create an incomplete Case_Routing_Rule__mdt record (missing Queue_Name__c, for instance) — skipping that one bad rule and logging it, rather than letting it silently corrupt the lookup or throw an exception that blocks every single Case insert in the org, is a meaningfully more robust design.
A data problem vs a genuine bug
A Case with a missing Priority, or a routing rule missing Queue_Name__c, are data problems — expected, handleable situations, not signs the code itself is broken. Neither deserves a thrown exception that halts the whole transaction; both deserve exactly what this lesson implemented: a graceful fallback and a debug log, keeping the feature working even with imperfect input data.
Exercise
Add a guard to buildRoutingLookup that skips (with continue) any rule missing Queue_Name__c, logging its Id first.
Show hint
String.isBlank(rule.Queue_Name__c)
Handle Errors Gracefully 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
This lesson hardens the routing logic against two real edge cases: a Case missing Priority or Type, and a malformed custom metadata rule — neither should crash the whole trigger.