0

I am trying to create some Apex validation that checks to see if there are any open Work Orders on a Case before allowing to close. The logic works, however, the error is not displaying correctly. Instead, I get the generic error message saying the record may have been deleted.

Here is my class:

public static void closeCaseValidation(List<Case> cases) {
    
    for( Case c : [SELECT Id, Status FROM Case
                 WHERE Id IN (SELECT CaseId FROM WorkOrder WHERE Status != 'Approved - Ready for Invoice' AND Status != 'Cancelled') AND
                 Id IN :cases]) {
            
        if (c.Status == 'Closed') {
            c.adderror('Cannot Close Case while there are Unapproved Work Orders.');
        }
    }
} 

And here is my trigger:

if (Trigger.isUpdate) {
        //Before Update
        blogic_Case.closeCaseValidation(Trigger.new);
} 

Instead of "Cannot Close Case while there are Unapproved Work Orders.", the error message is displaying "You encountered some errors when trying to save this record There's a problem saving this record. You might not have permission to edit it, or it might have been deleted or archived. Contact your administrator for help."

Edit:

New code after implementing suggestions below:

Class:

public static void closeCaseValidation(Map<Id,Case> cases) {
  
        
    for( Case c : [SELECT Id, Status FROM Case
                 WHERE Id IN (SELECT CaseId FROM WorkOrder WHERE Status != 'Approved - Ready for Invoice' AND Status != 'Cancelled') AND
                 Id IN :cases.values()]) {
            
        if (c.Status == 'Closed') {
            cases.get(c.Id).adderror('Cannot Close Case while there are Unapproved Work Orders.');
        }
    }
}

Trigger:

if (Trigger.isUpdate) {
    //Before Update
    blogic_Case.closeCaseValidation(Trigger.newMap);
} 
2

Your code needs to actually call addError on the record from Trigger.new/Trigger.newMap, otherwise it just throws an exception. Consider the following changes:

 //blogic_Case.closeCaseValidation(Trigger.new);
 blogic_Case.closeCaseValidation(Trigger.newMap);

...

//public static void closeCaseValidation(List<Case> cases) {
public static void closeCaseValidation(Map<Id,Case> cases) {

...

   //c.adderror('Cannot Close Case while there are Unapproved Work Orders.');
   cases.get(c.Id).adderror('Cannot Close Case while there are Unapproved Work Orders.');
| improve this answer | |
  • Thanks as always for the input. I've made the changes you suggested above; changing cases from a List to a Map and then utilizing the get() function when adding the error. This caused an error regarding the inability to iterate through a Map variable and I did some research and found I needed to change cases to cases.values() in my IN statement in the SOQL query. This compiled correctly but the issue still stands where the error text I added is not being displayed. – DC-Fencer Jul 14 at 17:58
  • @DC-Fencer What's the context for where the record is being updated? Have you checked the debug logs? – sfdcfox Jul 14 at 18:21
  • Editing it from the UI on the record page. When I run a debug log while I attempt to edit it is throwing the correct text - it just doesn't appear on the UI when editing it. Also apparently it still tries to run the AfterUpdate triggers and sends me an error update email for that but that seems to be a separate issue: 13:27:53.233 (320514120)|EXCEPTION_THROWN|[273]|System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Cannot Close Case while there are Unapproved Work Orders.: [] – DC-Fencer Jul 14 at 18:33
  • Is there potentially a handler class that wraps the whole trigger in a try/catch block? I've gotten weird results when there are caught exceptions thrown in nested blocks. – Todd Sprinkel Jul 14 at 19:38
  • @toddsprinkel I have figured out the issue though I don't fully understand the root causes. Posted a separate answer explaining. – DC-Fencer Jul 15 at 14:48
0

The issue has been resolved. Apparently the addError message would only appear in the UI when using the newMap case values set as a separate variable. I have changed the class to be the following:

public static void validationOpenWorkOrders(Map<Id,Case> newCases, Map<Id,Case> oldCases) {
    //Validation error that does not allow User to set a case's Status to Closed if there are open Work Orders.
    for (Case c : [SELECT Id, Status FROM Case
                 WHERE Id IN (SELECT CaseId FROM WorkOrder WHERE Status != 'Approved - Ready for Invoice' AND Status != 'Cancelled') AND
                 Id IN :newCases.values()]) {
                
        Case newCase = newCases.get(c.Id);
        Case oldCase = oldCases.get(c.Id);
        if (newCase.Status == 'Closed' && oldCase.Status != 'Closed') {
            newCase.adderror('Cannot Close Case while there are Unapproved Work Orders.');
        }
    }

} 

Adding in

Case newCase = newCases.get(c.Id);

And changing

//cases.get(c.Id).adderror('Cannot Close Case while there are Unapproved Work Orders.');
newCase.adderror('Cannot Close Case while there are Unapproved Work Orders.');

Solves the issue of the UI displaying the generic exception error instead of my custom text. Please note that there are some additional lines added in to solve a separate issue of needing to be able to re-open the Case if there were open Work Orders.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.