Depending on the situation, if possible I usually use the following method for my DML error handling.
public static void dmlErrorHandling(List<Database.SaveResult> srList, List<Contact> contactList, String additionalMessage)
{
List<Id> successIds = new List<Id>();
for (Database.SaveResult sr : srList)
{
if (sr.isSuccess()) { successIds.add(sr.getId()); }
}
if (successIds.size() != contactList.size())
{
for (Contact c : contactList)
{
if (!successIds.contains(c.Id))
{
// Handle the error, Note that you have access to the failed record
System.debug('DML failed for Contact with ID: '+ c.Id);
}
}
}
}
Just to clarify the logic here: You loop over the List of Database.SaveResult and add all the IDs of the records that didn't fail during DML, to a List of IDs. Then you loop over the initial List of records that you passed to the DML method (Insert/Update) and for each record ID you check to make sure it exists in the list of success IDs and if doesn't, there you have a record with failed DML and you can do whatever you'd like to from this point with the failed records.