2

I am trying to convert Database.Error to Database.DuplicateError and to Datacloud.DuplicateResult. Below is the code snippet (no compile time error) -

Datacloud.DuplicateResult dupError = (Datacloud.DuplicateResult)(((Database.DuplicateError)((Database.Error)saveRes.getErrors()[0])).getDuplicateResult());

Now I am getting below error on DML

Invalid conversion from runtime type Database.Error to Database.DuplicateError.

I am trying to do direct type conversion over here referring this code snippet by Salesforce. Is there anything which we can do over here or I have to follow the way the link is saying?

  • Do you have a testing snippet you're using to throw these errors? Anything a user could run in execute anon? Could be helpful – battery.cord Jun 26 '18 at 13:48
  • @battery.cord - I don't have any code to help you with. I have a suggestion about how you can replicate this. Try Insert/update any record in APEX with Database.insert/update. Intentionally provide the exception in this DML and in saveResult methods (!saveResult.isSuccess()) put this line of code you will get the exception. Please try this. – Rohit Jun 27 '18 at 6:53
  • So, more or less the code used to generate the sample in the documentation? Just wanted to make sure. – battery.cord Jun 27 '18 at 13:19
  • @battery.cord - I am unable to provide the code 2 reasons - – Rohit Jun 27 '18 at 16:22
3

I'm unable to repo this on my org (cs14, version 43). At first I thought it was due to something in your one-liner, since I used a expanded version (shown below), but that also worked fine.

I'd say its due to a DmlException being thrown, when your code expects a DuplicateError. Adding a hard failure (insert new Account();) to my account trigger causes the same error message, when using your one-liner:

System.TypeException: Invalid conversion from runtime type Database.Error to Database.DuplicateError

Personally, I think this is a fault on the authors of the documentation, since they try to cast a type without checking if its a member of that type. This is what instanceof is for. Adding a type-check before we do any casting to help handle different errors being mixed together should negate this problem entirely.

The line needed is someError instanceof Database.DuplicateError. The full code below was what I used to test.

String rawAccountJson = ''; // JSON Of an existing account used to create a duplicate of that account
// Use whatever values to trigger your rules 

// Create a dupe from our dupe json 
Account dupe = (Account)JSON.deserialize(rawAccountJson, Account.class);

Database.SaveResult result = Database.insert(dupe, false); // set false to avoid directly throwing an exception 

// One-Liner to ensure behavior is the same .. 
Datacloud.DuplicateResult dupError = (Datacloud.DuplicateResult)(((Database.DuplicateError)((Database.Error)result.getErrors()[0])).getDuplicateResult());

System.debug(dupError); // outputs raw exception data

// Should check each step of one-liner, instead of assuming theres n errors and that error[0] is of a type 

// Check sucess ...  
if (!result.isSuccess()) {

    // Insertion failed due to error 
    for(Database.Error duplicateError : result.getErrors()) {
        // !! Verify that record is a dupe before casting (via instanceof) !! 
        if (duplicateError instanceof Database.DuplicateError) {
            // Now that were type-safe, lets do our casting 
            Datacloud.DuplicateResult duplicateResult = ((Database.DuplicateError)duplicateError).getDuplicateResult();
            // Then debug our results 
            System.debug('Duplicate records have been detected by ' + 
                      duplicateResult.getDuplicateRule());
            System.debug(duplicateResult.getErrorMessage());
        } else {
            // Should catch all other errors 
            System.debug('Error thrown but not a dupe result');
        }
    }
}
  • thanks for detailed explanation. I will definitely check it and will provide you with the updates. And yes you logic seems right. – Rohit Jun 29 '18 at 9:36

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.