An exception in Apex is a runtime error that interrupts the normal flow of execution. When one is thrown and not caught, Salesforce rolls back all DML done in the current transaction, aborts execution, and surfaces the error — to the user in the UI, to the caller in an API response, or to the debug log in async contexts.
What “happens” when an exception fires
- Apex stops executing at the line that threw — no further code in that method runs.
- The runtime searches up the call stack for a
catchblock that matches the exception type. If it finds one, control transfers to that block. - If no
catchmatches, the exception is uncaught:- Synchronous contexts (trigger, controller, REST endpoint): the transaction rolls back, an
Apex Unexpected Exceptionis logged, and the user sees an error message. - Async contexts (Batch, Queueable, Future, Scheduled): the job is marked Failed in
AsyncApexJob. Salesforce sends an email to the user who submitted the job (and the email-on-failure recipient if configured). Other completed jobs in the chain still ran. - Triggers: the DML operation that fired the trigger is also rolled back.
- Synchronous contexts (trigger, controller, REST endpoint): the transaction rolls back, an
- Any
finallyblock on the stack still runs, regardless of whether the exception was caught.
Anatomy of an exception
Every Apex exception inherits from System.Exception and exposes:
getMessage()— human-readable textgetTypeName()— fully-qualified class name (e.g.System.DmlException)getLineNumber()— source line that threwgetStackTraceString()— full call stackgetCause()— wrapped lower-level exception, if any
try {
Account a;
a.Name = 'Acme'; // NullPointerException
} catch (Exception e) {
System.debug('Type: ' + e.getTypeName());
System.debug('Message: ' + e.getMessage());
System.debug('Line: ' + e.getLineNumber());
}
Why exceptions exist
Salesforce uses exceptions to enforce platform contracts. Hit a governor limit, miss a required field on insert, dereference a null pointer, or violate sharing — the runtime throws a specific exception type so your code can either recover or fail loudly. Silent failures would leave half-written data in a multi-tenant environment.
Categories of exception you’ll see
| Source | Example |
|---|---|
| Platform-thrown built-ins | DmlException, QueryException, NullPointerException, LimitException |
| Triggered by your own code | addError() in a trigger raises a record-level error |
| Custom | Any class extending Exception — throw new MyException('bad config') |
Common follow-ups
- Are LimitExceptions catchable? — No. Governor limit exceptions cannot be caught. You can
tryaround them but they bubble up regardless. - Does an exception in one trigger roll back another trigger’s changes? — Yes, the whole transaction is one unit.
- Can
finallyswallow an exception? — Only iffinallyitself throws, which replaces the original.
Verified against: Apex Developer Guide — Exception Handling. Last reviewed 2026-05-17 for Spring ‘26.