Skip to main content

Code reviews rule: Missing exception handling in database operations

Written by David Martin
Updated this week

Missing exception handling in database operations

Why is this an issue?

DML statements (insert, update, delete, upsert, merge, undelete) and Database.* methods throw a DmlException at runtime when an operation fails. If these operations aren't wrapped in a try-catch block, an unhandled exception will terminate execution, potentially leaving the database in an inconsistent state and providing a poor user experience.

Examples

Example of incorrect code:

public void createAccount(Account acc) {
insert acc;
}

Example of correct code:

public void createAccount(Account acc) {
try {
insert acc;
} catch (DmlException e) {
Logger.error('Failed to insert account', e);
throw new AccountServiceException('Could not create account', e);
}
}

How can I fix violations?

Wrap the DML operation in a try-catch block that handles DmlException. Consider what recovery or logging action is appropriate for your use case. Simply swallowing the exception is rarely the right approach.

Alternatively, use Database.* methods with the allOrNone parameter set to false. These return result objects (Database.SaveResult, Database.DeleteResult, etc.) instead of throwing exceptions, which you can use to determine partial success.

Database.SaveResult[] results = Database.insert(accounts, false);
for (Database.SaveResult result : results) {
if (!result.isSuccess()) {
for (Database.Error err : result.getErrors()) {
Logger.error(err.getMessage());
}
}
}

Resources

Did this answer your question?