Based on your comments, if you have a relationship between the two objects the error mapping is fairly straightforward.
Children
public static void createChildren(List<Parent__c> parents)
{
List<Child__c> children = new List<Child__c>();
for (Parent__c parent : parents)
{
Child__c child = new Child__c();
child.Parent__c = parent.Id;
children.add(child);
}
try
{
insert children;
}
catch (DmlException dmx)
{
Map<Id, Parent__c> parentMap = new Map<Id, Parent__c>(parents);
for (Integer i = 0; i < dmx.getNumDml(); i++)
{
Id parentId = children[dmx.getDmlIndex(i)].Parent__c;
parentMap.get(parentId).addError(dmx.getDmlMessage(i));
}
}
}
Parents
public static void updateParents(List<Child__c> children)
{
Map<Id, Parent__c> parentMap = new Map<Id, Parent__c>();
for (Child__c child : children)
{
Parent__c parent = new Parent__c(Id=child.Parent__c); // and updates
parentMap.put(child.Parent__c, parent);
}
List<Parent__c> parents = parentMap.values();
try
{
update parents;
}
catch (DmlException dmx)
{
Map<Id, List<Child__c>> parentToChildren = new Map<Id, List<Child__c>>();
for (Child__c child : children)
{
if (!parentToChildren.containsKey(child.Parent__c))
parentToChildren.put(child.Parent__c, new List<Child__c>());
parentToChildren.get(child.Parent__c).add(child);
}
for (Integer i = 0; i < dmx.getNumDml(); i++)
{
for (Child__c errorChild : parentToChildren.get(parents[i].Id))
{
errorChild.addError(dmx.getDmlMessage(i));
}
}
}
}
It might be worth adding a utility that will group the children by parent, i.e. static Map<Id, List<Child__c>> groupByParent(List<Child__c> children)
.
I also am not sure which is better but often I use dmx.getMessage()
instead of dmx.getDmlMessage(i)
.
DMLException
resulting from cross-object update can often be mapped back to the source of the error. ANullPointerException
should usually be refactored with a guard clause or some other strategy. You should always know what specifically you are trying tocatch
and avoid the "Pokemon catch" (gotta catch em all!)