In my batch classes, I’m a big user of the allOrNone
argument to Database.insert
or Database.update
. This is mostly because some orgs have dirty data and dealing with those as non-fatal exceptions is better for the business than rolling back all DML from a batch execute()
that might be dealing with 199 good records and only one bad one.
So, the normal pattern would be
Database.SaveResult[] srList = Database.update(listOfSobjs,false); for (Integer i =0; i < listOfSobjs.size(); i++) if (!srList[i].isSuccess() { // log the error somewhere for later admin action - typically to a persistent sobj }
But what if you had this coding fragment where the allOrNone
argument was a variable, sometimes true, sometimes false?
Database.SaveResult[] srList = Database.update(listOfSobjs,allOrNoneVbl); for (Integer i =0; i < listOfSobjs.size(); i++) if (!srList[i].isSuccess() { // log the error somewhere for later admin action - typically to a persistent sobj }
Well, and again the doc isn’t completely clear on this, if allOrNoneVbl
is true, no Database.SaveResult
s are returned and an exception is thrown. Here’s proof:
try { Database.SaveResult[] srList = Database.insert(new List<Account>{ new Account(), new Account()}, true); system.assert(false,'allOrNothing=true does not throw exception'); } catch (Exception e) { system.assert(false,'allOrNothing=true does throw exception'); }
Debug log:
DML_END|[2]
EXCEPTION_THROWN|[2]|System.DmlException: Insert failed. First exception on row 0;
first error: REQUIRED_FIELD_MISSING,
Required fields are missing: [Name]: [Name]
EXCEPTION_THROWN|[6]|System.AssertException: Assertion Failed: allOrNothing=true does throw exception
FATAL_ERROR|System.AssertException: Assertion Failed: allOrNothing=true does throw exception
Conclusion: If your batch
execute()
is intended to log errors and you sometimes useisAllOrNone
as true and sometimes as false in the sameexecute()
(because you are doing multiple DML operations), your logging code is more complex as the source of the error message is found in different places (i.e.Database.SaveResult
methodgetErrors()
versus caught exceptiongetMessages()
).