Implement exception handling in Apex, including custom exceptions as needed.

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, and finally blocks
      • Use multiple catch blocks if necessary
      • Use generic exception catcher
      • Throw custom exception
    • 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
    • Caught Exceptions
      • addError() to abort DML operations
      • ApexPages.message class can be used to display an error
      • Messaging 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 or QueryException
    • 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 the System name space

  • Types of Exceptions: these are the 24 specific exceptions in the System namespace
    1. AsyncException: problem with asynchronous operation
    2. CalloutException: problem with a web service operation
    3. DmlException: problem with a DML statement like insert of delete
    4. EmailException: problem with email such as delivery failure
    5. ExternalObjectException: problem with external object records
    6. InvalidParameterValueException: invalid method parameter problem
    7. LimitException: uncatchable exception when a governor limit has been exceeded
    8. JsonException: problem with JSON serialization and deserialization
    9. ListException: problem with lists, such as trying to access an index out of bounds
    10. MathException: problem with mathematical operations such as division by zero
    11. NoAccessException: problem related to unauthorized access to objects
    12. NoDataFoundException: problem that occurs when data does not exist
    13. NoSuchElementException: problem when trying to access a list item that is out of bounds
    14. NullPointerException: problem with dereferencing a null variable
    15. QueryException: problem with using SOQL query for assignment
    16. RequiredFeatureMissing: problem when code requires a feature that has not been enabled
    17. SearchException: problem with SOSL queries using search call()
    18. SecurityException: problem with static methods in Crypto class
    19. SerializationException: problem with data serialization in Visualforce
    20. SObjectException: problem with inserting or updating sObject records
    21. StringException: problem with string usage and operations
    22. TypeException: problem with type conversion of variables
    23. VisualforceException: problem related to a Visualforce page or controller
    24. XmlException: 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, and finally 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 last catch 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

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:
    1. Without arguments: custom exceptions can be instantiated without arguments:
      MyException me = new MyException(); throw me;
    2. 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;
    3. Chained exception: an exception from a previous exception is passed:
      MyException me = new MyException(e); throw me;
    4. String and exception: a string error message and a chained exception is passed:
      MyException me = new MyException('oops!', e); throw me;

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 and EmailExceptions have additional methods such as getDmlFieldNames and getDmlMessage

  • 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

  • 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() and Limits.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