function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
mariagusmariagus 

How can I get failure info after an upsert

Hi all,

 

My piece of code, tries to get some information about the records that make the upsert fails, so for instance, instead of getting just "duplicate External Id" as an error, I would like to know which record is causing this error and why

 

I tried this:

 

transient List<Database.UpsertResult> upsertResult = new List<Database.UpsertResult>();

try

{

    Schema.SObjectField externalIdField = myObject__c.Fields.ExternalId__c;

    List<UpsertResult> upsertResult = Database.upsert(myObjectList, externalIdField,true);

}

catch(Exception ex)

{

       String error = upsertResult + '';

       sendEmail(error);

}

 

But e-mail returns to me null,

 

Does anybody know how can I fix it or if there is other way to get which record is causing the error and why?

 

Many thanks in advance

 

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

 

List<UpsertResult> results = Database.upsert( values, false );

This is the correct means for discovering errors is to use:

 

 

 

for(UpsertResult theResult:results) {
  if(theResult.isSuccess)
    continue; // next item
  List<Database.Error> errors = theResult.getErrors();
  for(Database.Error theError:Errors) {
    if(theError.getStatusCode() == StatusCode.REQUIRED_FIELD_MISSING)
      // It's a required field missing error, so state that...
  }
}

If you get a FIELD_CUSTOM_VALIDATION_EXCEPTION, you know that it's one of your custom validation messages, which you can check for with getMessage()...

 

I hope this helps you in your quest. I know it's not a perfect solution, but at least you can easily identify the type of exception that occurred. Note that try/catch is not necessary if you use the Database.upsert( values, false ) version (the false means "do not throw exceptions on DML failures").

 

 

 

All Answers

Ritesh AswaneyRitesh Aswaney

How about first just try to print the exception in the catch block

 

catch(Exception ex)

{

System.debug(LoggingLevel.ERROR, e.getMessage());

       String error = upsertResult + '';

       sendEmail(error);

}

mariagusmariagus

Thanks for your replay ... but what I exactly need is to know why my process if failing. I mean,

 

if I catch the exception with ex.getMessage(), I get this:

 

Opportunity Name: Educational Testing Service
Error: Upsert failed. First exception on row 14; first error: DUPLICATE_VALUE, duplicate value found: ffm__SalesAgreementBillingLineExternalID__c duplicates value on record with id: a1mC00000004VeT: []

 

I know what this error means, but when the customer receives this e-mail, he doesn't know how to fix it, so I need to give him more information.

 

At the begining I though that List<DataBase.upserResult> could give me more information about this error ... but I think I was wrong, because it only stores info if the upsert is ok.

 

I was also thinking about check:

 

If(ex.getMessage().contains('DUPLICATE_VALUE, duplicate value found: 

                                                     ffm__SalesAgreementBillingLineExternalID__c duplicates value on record'))

{

     //translate the message to a one more friendly and send it on the e-mail

    

     String error = ' Opportunity Name: Educational Testing Service 
                                Error: Upsert failed. This opportunity line has wrong value on this field

     sendEmail(error);

 

    // Where the underline part would be a link to this opportunity line

}

 

But the problem is that the error message could be different if the org language is not English ...

 

Have you got any other idea about how can I get more information once the upsert faile?

 

Many thanks in advance.

sfdcfoxsfdcfox

 

List<UpsertResult> results = Database.upsert( values, false );

This is the correct means for discovering errors is to use:

 

 

 

for(UpsertResult theResult:results) {
  if(theResult.isSuccess)
    continue; // next item
  List<Database.Error> errors = theResult.getErrors();
  for(Database.Error theError:Errors) {
    if(theError.getStatusCode() == StatusCode.REQUIRED_FIELD_MISSING)
      // It's a required field missing error, so state that...
  }
}

If you get a FIELD_CUSTOM_VALIDATION_EXCEPTION, you know that it's one of your custom validation messages, which you can check for with getMessage()...

 

I hope this helps you in your quest. I know it's not a perfect solution, but at least you can easily identify the type of exception that occurred. Note that try/catch is not necessary if you use the Database.upsert( values, false ) version (the false means "do not throw exceptions on DML failures").

 

 

 

This was selected as the best answer
mariagusmariagus

Thanks!!

 

You gave me a really good idea :)