DML executed inside a catch block

ID

apex.correctness.dml_in_catch_block

Severity

high

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

medium

Resource

Error Handling

Language

Apex

Description

Reports a DML statement - insert, update, upsert, delete - written inside a catch block.

Rationale

A catch block runs while the transaction is already in trouble, and DML there can fail for its own reasons: the new exception replaces the original one, so the log records the failure of the error handler instead of the failure it was handling. If the first exception was a LimitException the second DML cannot succeed at all, and if the transaction is later rolled back, the row the handler wrote - usually the error log entry - disappears with it, which is exactly the record that was supposed to survive.

The following code illustrates the pattern detected by this rule:

public class ErrorLogging {

    public void save(Account a) {
        // FLAGGED: DML executed inside a catch block
        try {
            insert a;
        } catch (DmlException e) {
            insert new Error_Log__c(Message__c = e.getMessage());
        }
    }

    public void saveWithEvent(Account a) {
        try {
            insert a;
        } catch (DmlException e) {
            EventBus.publish(new Error_Event__e(Message__c = e.getMessage()));
        }
    }
}

Remediation

Collect what needs to be recorded and write it outside the try/catch, or persist it in a way that survives a rollback - Database.insert with allOrNone=false, a platform event published with EventBus.publish, or a separate Queueable. Keep the catch block itself to logging and adding the error to the record.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved