Error Handling and Debugging in Apex: Tips for Troubleshooting Effectively
Introduction
Salesforce developers working with Apex often face complex error scenarios and debugging challenges. This article delves into practical techniques and strategies for troubleshooting issues in Apex development.
Error Handling Techniques in Apex
Error handling techniques help to create a controlled and informative response to errors which is extremely important in Salesforce development.
Try-Catch-Finally Blocks
Apex’s try-catch construct is the foundation of error handling. It allows us to isolate risky code and manage exceptions when they appear. If an exception is thrown, it is caught and code in the catch block is executed. Finally block executes regardless of whether the operation succeeded or failed, ensuring any final tasks or resource cleanups are handled.
try {
Account acc = new Account(Name = null); // This will cause a required field error
insert acc;
System.debug('Statement after insert.'); // This does not execute because insert causes an exception
} catch (DmlException e) {
System.debug('The following exception has occurred: ' + e.getMessage());
} finally {
System.debug('Execution completed. Performing cleanup if needed.');
}
In this snippet, the try block contains the potentially error-prone operation, while the catch block captures and handles the DmlException. Without this structure, the entire transaction would fail. If you are interested in a more detailed explanation, please check the following Apex Developer Guide that provides Exception Handling Example step by step.
Using Exception Methods
Apex exceptions provide built-in methods to retrieve detailed information about errors, making them invaluable for debugging and error resolution. These methods can be called on exception instances to extract specific details.
- getMessage() - can be used to obtain the error message to be displayed to the user.
- getTypeName() - returns the type of exception (e.g., DmlException, NullPointerException).
- getLineNumber() - returns the line number of the exception.
- getCause() - returns the cause of the exception as an exception object (if available).
try {
Account acc = new Account(Name = null);
insert acc;
} catch (DmlException e) {
System.debug('Error message: ' + e.getMessage());
System.debug('Error type: ' + e.getTypeName());
System.debug('Error at line: ' + e.getLineNumber());
System.debug('Cause of the error: ' + e.getCause());
}
Combining these methods allows developers to generate detailed logs and improve error reporting so it is easier to catch and solve an issue.
Throwing Custom Exceptions
Default error messages are often too technical for end-users. We can provide user-friendly messages to enhance the overall experience. Custom exceptions are capable of specifying detailed error messages and have additional custom error handling in catch blocks.
catch (DmlException e) {
throw new CustomException('Oops! Unable to process your request. Please check the input values.');
}
Here, a custom exception replaces the generic DmlException message, making it easier for users to understand the issue.
Common Exceptions
The most common exceptions are DML Exceptions, Null Pointer Exceptions and Query Exceptions. Let’s see what are these exceptions and how we can handle them properly.
- DMLExceptions: can be any problem with a DML statement, usually the result of a required field not being set. Wrap DML operations in try-catch blocks and use Database.saveResult to track operation success or failure.
- NullPointerExceptions: can be any problem with dereferencing a null variable. Always check if an object is null before accessing its properties or methods.
if (myObject != null) {
System.debug(myObject.Name);
} else {
System.debug('Object is null');
}
- QueryExceptions: can be any problem with SOQL queries, such as assigning a query that returns no records or more than one record to a singleton sObject variable. Use a safe approach like List queries to avoid unhandled QueryException errors.
List<Contact> contacts = [SELECT Id, Name FROM Contact WHERE Email = :email LIMIT 1];
if (!contacts.isEmpty()) {
System.debug(contacts[0].Name);
} else {
System.debug('No contact found');
}
Debugging Tools and Techniques in Salesforce
Salesforce provides a lot of tools to help developers debug their code efficiently. That is why understanding when and how to use these tools is key to solving problems quickly.
- Debug Logs capture database operations, system processes, and errors that occur when executing a transaction or running unit tests. Can be enabled in Setup. Includes setting Log Level that helps to avoid unnecessary noise. It is recommended to use filters and search for keywords to pinpoint the root cause.
If you are interested in more detailed information about Debug Logs, check this Apex Developer Guide.
- System.debug() Statement is often the first line of defense in understanding code behavior. It is recommended to include clear context, such as variable values and execution flow, and use log categories (e.g., "INFO: Value of x is:") for better organization.
- Checkpoints in Developer Console can be added to specific lines in an Apex source code to provide additional information related to the lines.
Conclusion
Developers can streamline their troubleshooting process and deliver reliable applications by using try-catch-finally blocks, employing user-friendly error messages and mastering Salesforce's debugging tools. Adopting best practices not only simplifies development but also ensures a better experience for end-users which is extremely important.
Stay informed and elevate your Salesforce skills by exploring our blog for more in-depth tutorials, tips, and expert advice.

