2

Sometimes some of my orders and contracts are not define in the same date terms. That causes my system to throw an exception as follows:

Message: Insert failed. First exception on row 8; first error: FIELD_INTEGRITY_EXCEPTION, Order Start Date can't be earlier than the contract's start date.: Order Start Date: [EffectiveDate

The message is very clear; however the default exception message does not specify which row is having the issue while trying to commit the work.

I am committing as follows:

List<Order> orderToInsertList = new List<Order>();

// doing some processing

insert orderToInsertList;

Is there any way I can get the data of row culprit of the exception?

4
  • 1
    It says, "row 8", probably thats what you are looking for? Jul 31, 2018 at 11:11
  • It tells the row number; however, I would like to have access to the values of that particular row so that I can pinpoint the culprit of the exception. Jul 31, 2018 at 11:14
  • Are you using insert/update keywords or using Database methods? Jul 31, 2018 at 11:15
  • I am using the insert/update keywords. Jul 31, 2018 at 11:19

2 Answers 2

4

You can use Database.methods for this. Database methods returns us Saveresult which tells us about rows which were problematic.

List<Sobject> toBeinserted;// = your records to be inserted;
Savepoint sp = Database.setSavepoint();

Database.SaveResult [] sresultResultArray = Database.insert(toBeinserted,false);
List<Integer> errorRows = new List<Integer>();
for(Integer i=0; i < sresultResultArray.size();i++){
    Database.SaveResult sr = sresultResultArray[i];
    if(!sr.success){
        errorRows.add(i);
    }
}

if(errorRows.size()>0){
    //This means there was an error. Lets do roll back
    Database.rollback(sp); //To stop partial commits
    //errorRows contains the rows in toBeinserted which were probelematic
    System.debug(errorRows );

}

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. If the parameter is not set or is set true, an exception is thrown if the method is not successful.

You can also use your Map-like data structure to store rowNumer vs ErrorMessage encountered.

NOTE : We only get Save result when we enable partial commit, this can sometimes be not desired, so make sure you do a ROLLBACK, to reach the previous state,

Source: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_database.htm

4

Use Database Class methods to insert the Record and then you can easily be identified which records are failing.

Using Database method you can also partially commit the data into the system means only failed records will get inserted into the system.

Example

The following example shows how to obtain and iterate through the returned Database.SaveResult objects. It inserts two accounts using Database.insert with a false second parameter to allow partial processing of records on failure.

// Create two accounts, one of which is missing a required field
Account[] accts = new List<Account>{
    new Account(Name='Account1'),
    new Account()};
Database.SaveResult[] srList = Database.insert(accts, false);

// Iterate through each returned result
for (Database.SaveResult sr : srList) {
    if (!sr.isSuccess()) {
        // Operation failed, so get all errors                
        for(Database.Error err : sr.getErrors()) {
            System.debug('The following error has occurred.');                    
            System.debug(err.getStatusCode() + ': ' + err.getMessage());
            System.debug('Fields that affected this error: ' + err.getFields());
        }
    }
}

Source: - Database Methods

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