Skip to content

AfterDelete.ContinueOnError

Logs and swallows a Writer's or Dispatcher's exception, so the delete goes on. The rest of that handler's records and its Finalizer are skipped.

Interface

apex
public class AfterDelete {
    public interface ContinueOnError {
    }
}

AfterDelete.ContinueOnError has no methods: implementing it is the whole opt-in.

Example

apex
public with sharing class ContactWriter implements AfterDelete.Writer, AfterDelete.ContinueOnError {
    public Boolean writeOnAfterDeleteWhen(TriggerHandler.DeleteRecord record) {
        return record.isNotNull(Contact.AccountId);
    }

    public void writeOnAfterDelete(TriggerHandler.DeleteRecord record, TriggerHandler.UnitOfWork unitOfWork) {
        unitOfWork.toInsert(new Task(WhatId = ((Contact) record.getOldSObject()).AccountId, Subject = 'Review contact'));
    }
}

Good to Know

  • Add a Logger. The exception goes to the org's TriggerOrchestrator.Logger implementation. Without one it leaves no trace. See Errors & Logging.
  • A Writer gets a private unit. Unless it implements OwnUnitOfWork, its writes go to a unit that commits right after it. A failed Writer loses only its own writes.
  • Some errors still throw. TriggerHandler.TriggerHandlerException and TriggerOrchestratorException are logged, then rethrown. A System.LimitException cannot be caught at all.
  • The old row stays read-only. Writing a field on getOldSObject() throws a FinalException that nothing can catch.
  • Code outside the handler is not covered. An exception in afterDeleteHandlers(), bypassOnAfterDeleteWhen(), ownUnitOfWorkOnAfterDelete(), queryParentsOnAfterDelete() or the shared commit fails the delete.