fflib-apex-common icon indicating copy to clipboard operation
fflib-apex-common copied to clipboard

UnitOfWork commitWork() method thrown exception could have additional diagnostics

Open cropredyHelix opened this issue 6 years ago • 2 comments

The catch block in commitWork() on the line:

throw e

could be more helpful to the diagnostician.

Use Case 1:

  • registerNew / registerRelationship a chain of Parent__c and Child__c. Both SObjects have field Foo__c, both as required.
  • commitWork()
  • In your test, one or more of the inserted Parents/Child have a null value for Foo__c

What happens is the exception trace will print as System.DmlException Insert failed. First exception on row 1; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Foo]: [Foo__c]

Without digging through more of the log, you have no idea whether the Parent__c or Child__c SObject is where the problem lies.

Suggestion: The commitWork() method is aware of the SObjectType being inserted/updated/deleted and should echo that Sobject type in the thrown exception. Suppress the SObject Type if the exception occurs in work.doWork() as it won't be known. This works around inadequacy of SFDC exception messages for certain use cases. It can also help if a VR fails - and you want to know what SObject the VR is on - and you have Validation Rule logging turned off (as I almost always do).

Use Case 2: Inner Class Relationships, for loop:

for(Relationship relationship : m_relationships)
  relationship.Record.put(relationship.RelatedToField, relationship.RelatedTo.Id);

if relationship.RelatedTo is null, a null pointer exception is thrown but there is no diagnostic as to which relationship is at issue. If one is doing several registerNew/registerDirty/regsiterRelationship calls within one transaction, you have trouble tracing the problem without going to the debugger or debug statements.

Suggestion Wrap this in try-catch so additional diagnostics can be added before throwing a new exception

Use Case 3: In:

public class SimpleDML implements IDML
{
  public void dmlInsert(List<SObject> objList) {
   insert objList;
  }
..
}

You can get System.ListException Before Insert or Upsert list must not have two identically equal elements error but there is no diagnostic telling you which SObjectType (or, for that matter, the contents of objList) to tell you which registerNew(...) calls your code made that created duplicates/

Suggestion: see above use cases

cropredyHelix avatar May 16 '18 19:05 cropredyHelix

This is a great idea!

afawcett avatar Jun 24 '18 05:06 afawcett

Another great idea by @cropredyHelix that needs at least tagging as an enhancement. @agarciaffdc can you do the honors? 👍

afawcett avatar Feb 11 '19 02:02 afawcett