[SalesForce] How to capture duplicate rules in apex

I have the following duplicate rule:

enter image description here

I have Allowed Action on create and Action on edit but when I try to create a duplicate account in apex, I get an error:

System.DmlException: Insert failed. First exception on row 0; first error: DUPLICATES_DETECTED, Use one of these records?: []

I can try to capture it using the following try/catch but is there a more elegant way to check if a duplicate rule is hit or not?

Also, is there a way to detect the duplicate record found inside the catch? (Note I'm getting an empty array in the error)

    Account a = new Account();
    a.Name = 'Some account';
    a.BillingCity='City';
    a.BillingState='State';
    a.BillingStreet ='Street';
    a.BillingPostalCode='123';
    try{
        insert a;
    } catch(DMLException e){ 
        if(e.getMessage().contains('DUPLICATES_DETECTED')){
            //------DO SOMETHING HERE------
            System.debug('if');
        }
        System.debug(e);
    }

Best Answer

Yes, the example is in the documentation.

// Process the saved record and handle any duplicates
public PageReference save() {

    // Optionally, set DML options here, use “DML” instead of “false” 
    //   in the insert()
    // Database.DMLOptions dml = new Database.DMLOptions(); 
    // dml.DuplicateRuleHeader.allowSave = true;
    // dml.DuplicateRuleHeader.runAsCurrentUser = true;
    Database.SaveResult saveResult = Database.insert(contact, false);

    if (!saveResult.isSuccess()) {
        for (Database.Error error : saveResult.getErrors()) {
            // If there are duplicates, an error occurs
            // Process only duplicates and not other errors 
            //   (e.g., validation errors)
            if (error instanceof Database.DuplicateError) {
                // Handle the duplicate error by first casting it as a 
                //   DuplicateError class
                // This lets you use methods of that class 
                //  (e.g., getDuplicateResult())
                Database.DuplicateError duplicateError = 
                        (Database.DuplicateError)error;
                Datacloud.DuplicateResult duplicateResult = 
                        duplicateError.getDuplicateResult();

                // Display duplicate error message as defined in the duplicate rule
                ApexPages.Message errorMessage = new ApexPages.Message(
                        ApexPages.Severity.ERROR, 'Duplicate Error: ' + 
                        duplicateResult.getErrorMessage());
                ApexPages.addMessage(errorMessage);

                // Get duplicate records
                this.duplicateRecords = new List<sObject>();

                // Return only match results of matching rules that 
                //  find duplicate records
                Datacloud.MatchResult[] matchResults = 
                        duplicateResult.getMatchResults();

                // Just grab first match result (which contains the 
                //   duplicate record found and other match info)
                Datacloud.MatchResult matchResult = matchResults[0];

                Datacloud.MatchRecord[] matchRecords = matchResult.getMatchRecords();

                // Add matched record to the duplicate records variable
                for (Datacloud.MatchRecord matchRecord : matchRecords) {
                    System.debug('MatchRecord: ' + matchRecord.getRecord());
                    this.duplicateRecords.add(matchRecord.getRecord());
                }
                this.hasDuplicateResult = !this.duplicateRecords.isEmpty();
            }
        }

        //If there’s a duplicate record, stay on the page
        return null;
    }

    //  After save, navigate to the view page:
    return (new ApexPages.StandardController(contact)).view();
}

Basically, you can use allOrNone = false, and examine the errors. It includes which rules caused the error, and the matches that were found.

Related Topic