1

I've been looking around but haven't found a good explicit answer for handling when multiple validation rules fail simultaneously.

Let's say I have a custom object called MyObject__c with two different validation rules.

The first validation rule will be on a number field called SampleQuantity__c. If SampleQuantity__c < 10, it'll throw an exception saying "Your minimum quantity is 10"

The second validation rule will be on another number field called SampleHoursSpent__c. If SampleHoursSpent__c > 40, it'll throw an exception saying "You have spent the maximum number of hours per week. Please update overtime field."

I'll have something similar to the following when I update my record.

List<MyObject__c> myObjList = getObjects();
try {
      update myObjList;
} catch (DMLException ex) {
    /* this line will get both error messages if both of them fail simultaneously */
    ApexPages.addMessages(ex);

    /* however, if i try to get the number of dml exceptions with a loop,
     * there is only 1 
     */
    for (Integer i = 0; i < ex.getNumDml(); i++) {
        System.debug(ex.getDmlMessage(i));
    }
}

Why can I not see all the DML messages when I try to iterate over them, yet I am able to get them through ApexPages? Shouldn't the behavior be the same?

I've also tried browsing SFDC known issues, but couldn't find something that is related to this issue.

  • how many records you are updating, single or multiple? – Santanu Boral Aug 4 '16 at 3:18
  • @Justin If one of these answers addressed your problem, please consider accepting it by clicking on the check mark/tick to the left of the answer, turning it green. This marks the question as resolved to your satisfaction, and awards reputation both to you and the person who answered. If you have >= 15 reputation points, you may also upvote the answer if you wish. There is no obligation to do either. – Adrian Larson Aug 5 '16 at 19:37
2

I can presume you are doing multiple updates at a time.

If it is a single update, the first validation error it get captured in catch block and it will not execute again, because of update statement.

I think if you use Database.update() you will get all the DML messages for multiple records which are getting failed.

Database.SaveResult[] update(sObject[] recordsToUpdate, Boolean allOrNone)

allOrNone Type: Boolean

The optional allOrNone parameter specifies whether the operation allows partial success. If you specify false for this parameter and a record fails, the remainder of the DML operation can still succeed. This method returns a result object that can be used to verify which records succeeded, which failed, and why.

  • I am updating a list of records all at once. Thank you for your help. I'll give it a try and let you know after. – Justin Aug 4 '16 at 4:43
2

@Santanu makes a great point that I would like to expand on a bit. Note in the Database.SaveResult class that there is a getErrors() method that returns a List<Database.Error>. This collection is what you need to iterate through.

Database.SaveResult result = Database.insert(record, /*allOrNone*/ false);
for (Database.Error error : result.getErrors())
{
    // all results will be here
}

Also note that there are different *Result objects depending on your DML operation, but they all share this method.

Database.UpsertResult result = Database.upsert(record, false);
Database.DeleteResult result = Database.delete(record, false);
Database.UndeleteResult result = Database.undelete(record, false);
Database.EmptyRecycleBinResult result = Database.emptyRecycleBin(record, false);

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.