12

Each instance of a Database.SaveResult corresponds to a result of a DML operation on a single record. According to the documentation, the method to get error details for a record actually returns an array of Database.Errors instead of a single error.

  1. What are the instances when multiple errors occur?
  2. Inside each Error, we can further find getFields() why is this in plural again?
  3. Is there a proper way to construct a complete error message with all this information?

The 3rd question is because I have a pair of related objects and when the child record is updated, it flows to the parent record and if an error occurs in the parent update, I need to pass the details to the child record via a .addError(). I have complex triggers on both objects and I use optAllOrNone as false while inserting/updating the child record.

2 Answers 2

10
  1. Each field may return an independent error (e.g. multiple validation rules failed). In this case, the API allows to report each error on the appropriate field. Remember, this is an API that can be used to show errors on a third-party application, so reducing the number of round-trips is important. It could be from, for example, a half-dozen validation rules that all failed, or from an Apex Trigger that used addError to report errors. Also, errors can appear on the record level, in which case getFields() won't return anything.

  2. Each error may be associated with multiple fields. While this is rare, it is possible for some validations to appear on multiple fields at the same time. For example, you can't use EndDateTime and DurationInMinutes on a single event (you have to specify one or the other, or at least they must agree), and you can't specify UnitPrice, Quantity, and TotalPrice on an opportunity line item (choose two); in this case, the error appears on all fields involved. One specific field can't be flagged because the user needs to choose which is the correct value.

  3. That depends on how specific you need to be. Normally, I just return the first error, since there's rarely more than one in a cascade update (you should know know how to properly update the child records until someone adds an error/validation downstream). You could even return a generic error message stating that a child update failed. On the other hand, you might choose to not display the errors to the user, but email them to an administrator, since the user "may not" know how to handle the error anyways, and the administrator may need to handle that situation independently.

1
  • In total agreement about 3. In my case, it's an ETL which needs to know there was an error and because of the volume of data it might be impractical for admins to work on individually
    – LVS
    Jul 12, 2014 at 21:54
3

The save triggers a transaction. The transaction doesn't fail and get blocked immediately, but if there are several validation failures, each gets bundled up in its own instance of Database.Error for you to check.

To illustrate this I created two validation rules on account. One if the account name was too short (fewer than 5 characters), the other that all prospects must be high priority.

I then ran this anonymous block:

Account a = new Account();
a.Name = 'tiny';
a.CustomerPriority__c = 'Medium';
a.Type = 'Prospect';

List<Database.SaveResult> srs = Database.insert(new List<Account>{a}, false);

for (Database.SaveResult sr : srs){
  System.debug('error size: '+sr.getErrors().size());
  //---------->size is 2
  for (Database.Error err : sr.getErrors()){
    System.debug(err);
    //----------each error object output to log
  }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .