Implement exception handling in Apex, including custom exceptions as needed.
These are technical notes I compiled while studying using Focus on Force, a company that provides Salesforce training and certification prep services.
After studying this topic, you should be able to:
- Identify the different types of exceptions in Apex
- Determine how to implement exception handling in Apex
- Describe how to create and use a custom exception
Table of Contents
- What are Exceptions
- Exception Examples
- Exception Handling
- Custom Exceptions
- Exception Methods
Introduction
- This topic describes how to implement exception handling in Apex with examples of built-in exceptions.
- Also explains how exception methods and custom exceptions can be used in Apex
- Exception handling allows developers to try running some code, catch a potential exception, and run a block of code whether there is an exception or not
- Salesforce provides a comprehensive framework for handling server-size exceptions on the platform
- Types of Exceptions: built-in exceptions, custom exceptions
- Exception Handling:
- Use
try
,catch
, andfinally
blocks - Use multiple catch blocks if necessary
- Use generic exception catcher
- Throw custom exception
- Use
- Exception Methods:
- Use
getMessage()
to obtain error message - Use
getCause()
to return cause of exception - Use
getLineNumber()
to return exception line number - Use
getTypeName()
to return type of exception
- Use
- Caught Exceptions
addError()
to abort DML operationsApexPages.message
class can be used to display an errorMessaging
class can be used to send errors via email- Future methods can be used to store error messages
- Uncatchable Exceptions
LimitException
cannot be caught- Use
Limit
methods for governor limits Assert
statement failures cannot be caught
What are Exceptions
- Exceptions are caused by errors encountered when executing code, which disrupt the normal flow of code execution
- Handled or Unhandled: Exceptions can be handled using the exception handling framework, or they can be unhandled when there is no code to deal with the exception
- Built-in and Custom: Apex includes a framework to deal with built-in exceptions, and it is also possible for developers to create custom exceptions
- Built-in Exceptions: exceptions can be built-in, ex:
NullPointerException
orQueryException
- Custom Exceptions: custom exceptions can be created and are designed to be thrown explicitly
- Multiple Exception Types: Apex provides the generic
Exception
class plus 24 different types of built-in exceptions in theSystem
name space
- Types of Exceptions: these are the 24 specific exceptions in the
System
namespaceAsyncException
: problem with asynchronous operationCalloutException
: problem with a web service operationDmlException
: problem with a DML statement like insert of deleteEmailException
: problem with email such as delivery failureExternalObjectException
: problem with external object recordsInvalidParameterValueException
: invalid method parameter problemLimitException
: uncatchable exception when a governor limit has been exceededJsonException
: problem with JSON serialization and deserializationListException
: problem with lists, such as trying to access an index out of boundsMathException
: problem with mathematical operations such as division by zeroNoAccessException
: problem related to unauthorized access to objectsNoDataFoundException
: problem that occurs when data does not existNoSuchElementException
: problem when trying to access a list item that is out of boundsNullPointerException
: problem with dereferencing a null variableQueryException
: problem with using SOQL query for assignmentRequiredFeatureMissing
: problem when code requires a feature that has not been enabledSearchException
: problem with SOSL queries using searchcall()
SecurityException
: problem with static methods in Crypto classSerializationException
: problem with data serialization in VisualforceSObjectException
: problem with inserting or updating sObject recordsStringException
: problem with string usage and operationsTypeException
: problem with type conversion of variablesVisualforceException
: problem related to a Visualforce page or controllerXmlException
: problem with the XmlStream classes, such as failure to read XML
Exception Examples
- SOSL Query causes a QueryException: thrown when there is an error encountered involving a query
- Ex: SOSL query returns more than one result but is being assigned to a single sObject, which causes QueryException to be thrown
// SOSL query returns more than one result but is being assigned
// to a single sObject, which causes QueryException to be thrown
Account myAccount = [SELECT Id, name
FROM Account
WHERE Name = 'ACME'];
- QueryException Error: caused by assigning multiple sObject rows to a variable that expected a single sObject row
- Null Value causes a
NullPointerException
: thrown when there is an error related to dereferencing a null value of a variable
// The value of a is null, which causes a NullPointerException
Integer a;
String s;
s = a.format();
System.debug('Value of s: ' + s);
Exception Handling
- Exception handling in Apex is implemented using
try
,catch
, andfinally
blocks, which allow code to handle and recover from exceptions- Try block: code for business logic is run within a
try
block - Catch block: if an exception is thrown, it is caught and code in the catch block is executed
- Finally block: code in finally block is run whether an exception has been thrown or not - used for cleanup
- Multiple catch blocks: multiple catch blocks can be used to catch different types of exceptions
- Generic exception: when the generic
Exception
is used, it must be implemented as the lastcatch
block - Uncaught exceptions: when exception handling is not implemented, the developer and running user get notified of uncaught exceptions
- Caught exceptions: when caught, the default notification mechanisms are not used
- Try block: code for business logic is run within a
Multiple Catch Blocks example
try {
List<Integer> numbers = new List<Integer>{1,2,3};
System.debug(numbers.get(3));
} catch (DmlException e) {
System.debug('An error was encountered when performing a DML operation');
} catch (QueryException e) {
System.debug('An error was encoutered when performing a SOQL query');
} catch (Exception e) {
// Generic exception should always be the last catch block if used
// Otherwise, code will not compile
System.debug(e.getTypeName() + ' was thrown! ' + e.getMessage());
} finally {
System.debug('Finally block');
}
Custom Exceptions
- Custom exceptions can be used to deliberately throw and catch exceptions in methods
- Custom handler behavior: custom exceptions can specify detailed error messages and have additional custom error handling
- Extend exception class: custom exceptions are created by extending the built-in
Exception
class - Interrupt program flow: custom exceptions can be used to interrupt the program flow even when a system exception does occur
- Explicitly throw exception: using the
throw
keyword
- Four ways to construct a custom exception:
- Without arguments: custom exceptions can be instantiated without arguments:
MyException me = new MyException(); throw me;
- String error message: string argument can be passed to its constructor which will be used as the error message:
MyException me = new MyException('oops!'); throw me;
- Chained exception: an exception from a previous exception is passed:
MyException me = new MyException(e); throw me;
- String and exception: a string error message and a chained exception is passed:
MyException me = new MyException('oops!', e); throw me;
- Without arguments: custom exceptions can be instantiated without arguments:
Custom Exception Example
The following shows a custom exception class called CustomException
where an instance is being thrown in a simple try-catch
block if a certain condition is met:
//Definition of Custom Exception
public class CustomException extends Exception{}
//CustomException Handling using try, throw and catch
try {
Integer a;
//Code block
if (a >100 ) throw new CustomException();
} catch (CustomException e) {
//CustomException Handling code
}
Exception Methods
- All built-in and custom exceptions have common methods:
- Exception details: exception methods may be used to obtain more information about the exception
- Message and type: exception methods can be used to return the error message and exception type
- Error message: for example,
getMessage
method can be sued to obtain the error message to be displayed to the user - Error cause: the
getCause
method returns the cause of the exception as an exception object - Line number: the
getLineNumber
method returns the line number of the exception - Error type: the
getTypeName
method returns the type of exception - Other methods:
DMLExceptions
andEmailExceptions
have additional methods such asgetDmlFieldNames
andgetDmlMessage
- Following illustrates the different types of info that can be retrieved using the common methods available in an
Exception
instance:
try{
//Causes a QueryException because the query result contains
//multiple accounts but it is assigned to one object
Account acc = [SELECT Name FROM Account Limit 2];
} catch(Exception e) {
System.debug('Exception type: ' + e.getTypeName());
System.debug('Message: ' + e.getMessage());
System.debug('Cause: ' + e.getCause()); // returns null due to no previous inner exception
System.debug('Line number: ' + e.getLineNumber());
System.debug('Stack trace: ' + e.getStackTraceString());
}
- Handling Catchable Exceptions: Following are some actions to consider when handling caught exceptions:
- Prevent DML Operation:
addError()
method can be called on a record or field to prevent DML operations from committing - Display error message:
ApexPages.message
class can be used to show errors related to exceptions caused by a custom controller or controller extension for a Visualforce page - Email error messages: error messages can be sent to a developer via email using the Messaging class
- Store error messages: error details can be stored in a custom object using a future method
- Prevent DML Operation:
- Handling Uncatchable Exceptions: exceptions that require the termination of code execution and do not allow code to resume:
- Limit exceptions: result from exceeding governor limits
- Use limit methods: such as
Limits.getDMLRows()
andLimits.getLimitDMLRows()
can be used to obtain information regarding governor limits - Assert exceptions: exceptions thrown due to the failure of assertion statements like
System.assert
cannot be caught