Salesforce offers a variety of exceptions that developers might encounter when working with its Apex programming language. Understanding these exceptions and how to handle them is crucial for robust and error-free Salesforce development. Here’s an exhaustive list of common Salesforce exceptions, along with code examples that could potentially result in each exception, and best practices for handling them.
1. QueryException
- Cause: Occurs when there is an issue with a SOQL query, such as an incorrect query syntax or querying for fields that don’t exist.
- Example:
List<Account> accounts = [SELECT NonExistingField FROM Account];
Best Practice: Always verify your SOQL queries in the Developer Console and ensure field names and objects exist and are correctly spelled.
2. DmlException
- Cause: Happens when a DML (Data Manipulation Language) operation (insert, update, delete) fails.
- Example:
Account acc = new Account(); insert acc; // Fails because mandatory fields are not set
Best Practice: Ensure all mandatory fields are set before performing DML operations and use try-catch blocks to handle these exceptions.
3. NullPointerException
- Cause: Occurs when trying to access a method or property of an object that is null.
- Example:
Account acc; System.debug(acc.Name); // Throws NullPointerException
Best Practice: Always check if an object is null before accessing its properties or methods.
4. ListException
- Cause: Triggered when there is an issue with list operations, like accessing an index out of bounds.
- Example:
List<Integer> numbers = new List<Integer>{1, 2, 3}; Integer num = numbers[3]; // Index out of bounds
Best Practice: Check the size of the list before accessing elements by index.
5. LimitException
- Cause: Salesforce has strict Governor Limits, and this exception is thrown when these limits are exceeded.
- Example:
for(Integer i=0; i<100000; i++){ Account acc = new Account(Name='Test'+i); insert acc; // Exceeds DML limits }
Best Practice: Always be aware of Governor Limits and write optimized code to stay within limits.
6. NoSuchElementException
- Cause: Thrown when attempting to access an element in a collection that doesn’t exist.
- Example:
Iterator<Account> it = [SELECT Id FROM Account].iterator(); while(true) { Account acc = it.next(); // Fails when there are no more elements }
Best Practice: Check if the next element exists using
iterator.hasNext()
before callingnext()
.
7. TypeException
- Cause: Occurs when there is a mismatch in data types, like assigning a string to an integer.
- Example:
Integer num = '123'; // Type mismatch
Best Practice: Ensure data types are compatible when assigning values.
8. MathException
- Cause: Triggered by mathematical errors, such as division by zero.
- Example:
Integer a = 1 / 0; // Division by zero
Http http = new Http(); HttpRequest request = new HttpRequest(); request.setEndpoint('https://nonexistent.example.com'); HttpResponse response = http.send(request); // Fails if the endpoint is not reachable
Best Practice: Check for divisor being zero before division and handle other mathematical edge cases.
9. LockException
- Cause: Happens when there is a record locking issue, often in concurrent data operations.
- Example:
// Assuming two different processes are updating the same record at the same time Account acc = [SELECT Id FROM Account LIMIT 1 FOR UPDATE]; update acc;
Best Practice: Design your logic to handle record locking and concurrency appropriately.
10. CalloutException
- Cause: Occurs when there is an issue with an external callout, like a timeout or authentication error.
- Example:
Http http = new Http(); HttpRequest request = new HttpRequest(); request.setEndpoint('https://nonexistent.example.com'); HttpResponse response = http.send(request); // Fails if the endpoint is not reachable ```
Best Practice: Handle exceptions for external callouts and check endpoint availability and correctness.