The reason your catch block is not being executed is because of the false parameter you are passing in:
Database.update(accounts, false);
That parameter is called is_all_or_none
meaning treat the transaction atomically. If something fails, then make the entire transation fail. The reason for atomicity is pretty standard here...if one of my records fails to save, if an error occurs, I want to ensure that everything I attempted will roll back, preventing data from being out of sync.
When you set this to false, what that means is that if one record has an exception, validation rule failure (which actually is just a thrown exception), Trigger validation failure (myObje.addError(...)
which also is just a thrown exception) that one record will fail to save, but any other records in the batch will complete just fine.
In your dexcription, you write:
So to avoid this I use the Database.update() function to update accounts even if some DML exception occur.
This is a misunderstanding of the purpose as you can hopefully now see. Using Database.update isn't a way to bypass validation rules. It is a way to prevent one validation rule failure from causing many good records from failing.
To get your save to work, you need to understand what your validation rule failure is, and then attempt to save data that meets the validation criteria that have been set in your system. You could also evaluate whether this validation rule is actually meaningful anymore and make a choice to remove it, but I would not recommend this without thoughtful review, and checking with others who are using your org.
As to why the second System.debug()
is not being called (system.debug('two')
) that is extremely puzzling. Are you certain it is not?
Finally, when you use the is_all_or_none=false
version of DML (it also exists for insert, upsert, delete, and undelete), the way you look for failed records is as follows:
List<Database.SaveResult> results = Database.update(accounts, false);
for (Database.SaveResult result : results) {
if (!result.isSuccess()){
for (Database.Error err : result.getErrors()){
System.debug('Error: '+ err.getStatusCode() + ' ' + err.getMessage());
}
}
}
system.debug('two')
orsystem.debug(txt)
. If it is the first, that is extremely puzzling. If it is the second it is because by using thefalse
parameter you are preventing any exceptions from being thrown, and you must loop through theDatabase.SaveResult
list to inspect for failures as I showed in my answer below. In your debug log, filter on USER_DEBUG (case sensitive) and verify that you are not getting the debug.system.debug('two')
is not executed. Puzzling, yeah like you said !