Handle Returned Database Errors in Apex

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 1,564 other followers
Advertisements
Advertisements
  • Restriction Rules: Enhancing Data Security and Access Control in Salesforce
    Salesforce is a powerful customer relationship management (CRM) platform that enables businesses to manage their customer data, sales, and marketing efforts in one place. As a cloud-based platform, Salesforce allows users to access their data from anywhere, at any time. However, there are times when a user needs to restrict access to certain records or […]
  • Create Eye-Catching Typing Text Animations in LWC
    When it comes to creating engaging user interfaces, one of the most effective techniques is to create animations and effects that simulate real-world behavior. One such effect is the typing effect, where text appears to be typed out on a screen one character at a time. In this blog post, we will learn how to create a LWC component that displays text-like typing.
  • Add Some Fun to Your Salesforce Pages with a Confetti Generator LWC
    Confetti is a fun and playful way to celebrate special occasions, events, or simply add a touch of excitement to any project. In this blog post, we’ll walk through the process of creating a Confetti Generator component in Salesforce Lightning Web Components (LWC). Introduction Lightning Web Components (LWC) is a new programming model for building […]
  • Implementing Field-Level-Security in LWC for lightning-input Components
    Implementing Field-Level-Security (FLS) in Lightning Web Components (LWC) is an important aspect of building secure and customized applications. FLS is a security feature in Salesforce that allows administrators to control access to fields based on a user’s profile. This helps in preventing unauthorized access to sensitive information and maintaining data privacy.
  • Looping in Salesforce Apex: A Comprehensive Guide
    Loops are a fundamental programming concept that allows you to repeat a block of code multiple times. In Salesforce Apex, loops are used to process large collections of data, automate repetitive tasks, and much more. In this blog post, we’ll cover the different types of loops available in Salesforce Apex, when to use each type, and how to write effective looping structures in Apex.
  • LWC OSS: Unleashing the Power of Modern Web Development
    Lightning Web Components (LWC) Open Source (OSS) is a framework for building fast and efficient web applications with modern web technologies. This framework provides a set of tools and components for developers to build and deploy web applications quickly and easily.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s