Handle Returned Database Errors in Apex

Handling errors in the partial insert/update is best practice. As a developer, you should design the solution in a way that you can respond quickly when businesses ask questions about any failure.

While DML statements always throw exceptions when an operation fails for one of the records being processed and the operation is rolled back for all records, Database class methods can either throw exceptions and all records rolled back OR allow partial success for record processing.

Database class methods do not throw exceptions in the case of partial processing Instead, they return a list of errors that occurred on failed records.

The errors contain information about the failures and are returned by the Database class method. For insert and update operations, for example, a SaveResult object is returned. SaveResult, like all returned results, has a method called getErrors that returns a list of Database. Error objects, which represent any errors encountered.

â§” Example

This example demonstrates how to retrieve the errors returned by a database.update operation. It updates contacts, one of which lacks the correct mailing city field value, and sets the second parameter to false: update(contactList, false); into database.update, This option enables partial processing.

↠ A batch class is written to copy/update the billing city of an account into the mailing city of its related contact.

↠ A validation rule is written on the contact object to prevent the update if the ‘Test’ keyword is provided in the mailing city.

As a Salesforce developer, you’ve been tasked with handling error records and logging the error details in the custom object so that users can see what happened and why a few contact records weren’t updated.

✓ Solution ↴

BatchUpdateContactMailingCity.cls 

global with sharing class BatchUpdateContactMailingCity implements Database.Batchable<SObject>{
global Database.QueryLocator start(Database.BatchableContext bc){
String query = 'Select Id, BillingCity,(Select Id,Name, MailingCity from contacts) from Account';
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext bc, List<Account> accList){
//list of contacts to update
List<Contact> conListToUpdate = new List<Contact>();
for(Account acc: accList){
for(Contact con: acc.contacts){
con.MailingCity = acc.BillingCity;
conListToUpdate.add(con);
}
}
if(conListToUpdate.size()>0){
List<Database.SaveResult> updateResults = Database.update(conListToUpdate,false);
List<SObject> objList = new List<SObject>();
objList.addAll(conListToUpdate);
//call generic method to create the error log records
Util.createError(updateResults,objList,'Contact Update');
}
}
global void finish(Database.BatchableContext bc){
//add the finish code here
}
}

How to get the Id of the record from Database.SaveResult where Update failed?

To get the Id of the failed record, we can use the List index Property. The index of the List we are updating and the result set retrieved are both the same.

Util.cls

public with sharing class Util {
/**
* @author SFDC Lessons
* @description Method to create the error log record
* @param List<Database.SaveResult> saveResults
* @param List<SObject> objectList
* @param String topic
* @return void
*/
public static void createError(List<Database.SaveResult> saveResults, List<SObject> objectList, String topic){
try{
//error object list
List<Error_Log__c> errorList = new List<Error_Log__c>();
for( integer i=0; i < saveResults.size(); i++ ){
if (saveResults.get(i).isSuccess()) {
//add the code here if you want to do something in success case
}//error case
else if(! saveResults.get(i).isSuccess()){
// Operation failed, so get all errors
Database.Error dbError = saveResults.get(i).getErrors().get(0);
system.debug('Failed record id: '+ (String) objectList[i].get('Id'));
String recordId, recordName = '';
if(objectList.size()>0){
recordId = (String) objectList[i].get('Id');
recordName = (String) objectList[i].get('Name');
}
Error_Log__c err = new Error_Log__c();
err.Error_Message__c = dbError.getMessage();
err.Stack_Trace__c = String.valueOf(dbError.getStatusCode());
err.Record_ID__c = recordId;
err.Record_Name__c = recordName;
err.Topic__c = topic;
//add error in the list
errorList.add(err);
}
}
if (errorList.size()>0) {
insert errorList;
}
}catch(Exception e){
System.debug('Exception has occured! ' + e.getMessage());
}
}
}
view raw Util.cls hosted with ❤ by GitHub

Summary

Handling errors in the partial insert/update is best practice. As a developer, you should design the solution in a way that you can respond quickly when businesses ask questions about any failure.

Join 326 other subscribers
Advertisements
Advertisements
  • AlertFlow: Build a Configurable Notification Banner System for Salesforce
    The article discusses implementing a notification banner system in Salesforce to alert users about critical account information, such as sanctions or credit holds. It highlights four key problems this solution addresses, eliminates the need for coding to create alerts, and provides a step-by-step installation guide for the AlertFlow package.
  • A Practical Guide to Salesforce-to-QuickBooks Sync Problems
    Many organizations still use disconnected systems despite the growth in business software, leading to inefficiencies in data sharing. A well-executed integration between Salesforce and QuickBooks can resolve these issues. This guide outlines common integration challenges, potential solutions, and tips for achieving efficient synchronization between the two platforms.
  • From Zero to 100: How AgentExchange Became Salesforce’s Fastest-Growing App Publisher
    AgentExchange has published 100 apps in six months, achieving significant growth with 122 unique apps and 102 developers. The platform’s rapid expansion demonstrates the increasing demand for Salesforce-native solutions, particularly in sales and analytics. By offering reusable AI building blocks, AgentExchange enhances productivity and innovation within the Salesforce ecosystem.
  • Shopify + Salesforce: How to Build a Seamless Ecommerce Engine
    Integrating Shopify with Salesforce streamlines e-commerce operations by eliminating data silos. The integration synchronizes orders and customer information for accurate reporting and smarter marketing. This synergy improves operational efficiency, enhances customer support, and ensures reliable growth. Proper planning and phased implementation are vital for success and maintaining data integrity as businesses scale.
  • Linking Google Sheets to Salesforce: Full Guide
    Integrating Google Sheets with Salesforce using G-Connector simplifies data management by enabling two-way data synchronization. This allows users to automate reporting, reduce manual data entry errors, and improve collaboration. Teams can easily update records, share live data, and leverage Google Sheets’ tools for insightful analysis, enhancing productivity and efficiency.
  • Custom Email Tracking and Logging in Salesforce
    In Salesforce, tracking email engagement is vital for enhancing customer service and sales strategies. Although built-in features exist, they fall short in tracking link clicks and emails from Cases. This article outlines a custom solution using Apex and Flow to effectively monitor email opens and clicks, improving overall communication efficacy.
Arun Kumar
Arun Kumar

Arun Kumar is a Salesforce Certified Platform Developer I with over 7+ years of experience working on the Salesforce platform. He specializes in developing custom applications, integrations, and reports to help customers streamline their business processes. Arun is passionate about helping businesses leverage the power of Salesforce to achieve their goals.

Articles: 162

Leave a Reply

Discover more from SFDC Lessons

Subscribe now to keep reading and get access to the full archive.

Continue reading

Discover more from SFDC Lessons

Subscribe now to keep reading and get access to the full archive.

Continue reading