Retrying Unsuccessful Callouts in Salesforce Apex: Recommended Approaches with Code Examples

Discover effective strategies and code examples for enhancing reliability and error handling by implementing best practices when retrying failed callouts in Salesforce Apex.


In Salesforce Apex, callouts serve as a means to establish communication with external systems and APIs. However, these callouts may encounter failures, whether due to network issues or API errors, leading to errors within your Apex code. To enhance reliability and fortify error handling, it is imperative to incorporate retry logic for situations where callouts fail.

This blog post explores best practices for retrying failed callouts in Salesforce Apex and furnishes accompanying code snippets to facilitate your implementation.

Best Practices for Retrying Failed Callouts:

  1. Set a maximum number of retries: It is essential to establish a cap on the number of times you retry a failed callout to avoid potential issues like infinite loops and excessive API usage. A recommended approach is to set a maximum number of retries, such as three or five.
  2. Add a delay between retries: Introducing a pause between retry attempts can prevent overloading the external system or API, thereby enhancing the likelihood of success on subsequent tries. A suggested delay is at least five seconds.
  3. Catch specific exceptions: When handling exceptions during a callout, it is crucial to capture specific exceptions rather than general ones. For instance, consider catching System.CalloutException for general callout exceptions or System.HttpException for HTTP-specific exceptions.
  4. Implement exponential backoff: Adopting exponential backoff as a retry strategy involves progressively increasing the delay between retries with each subsequent attempt. This strategy aids in minimizing API usage and improving the likelihood of success in subsequent retries.

Code Snippet for Retrying Failed Callouts:

The following code snippet illustrates how to implement retry logic for failed callouts in Salesforce Apex:

public class makeCallout {
    
    public static HttpResponse makeCallout(String url, String method, String body) {
        HttpRequest request = new HttpRequest();
        request.setEndpoint(url);
        request.setMethod(method);
        request.setBody(body);
        
        Integer numAttempts = 3; // Maximum number of retry attempts
        Integer delayMillis = 5000; // Delay in milliseconds between attempts
        
        while (numAttempts > 0) {
            try {
                Http http = new Http();
                HttpResponse response = http.send(request);
                if (response.getStatusCode() >= 200 && response.getStatusCode() < 300) {
                    // Callout was successful, return response
                    return response;
                }
                // Callout was not successful, decrement attempts and retry
                numAttempts--;
            } catch (Exception ex) {
                // An exception occurred during the callout, decrement attempts and retry
                numAttempts--;
            }
        }
        // Maximum number of retry attempts reached, return null
        return null;
    }    
}

In this illustration, we establish a limit of three retry attempts with a five-second interval between each attempt. Additionally, we incorporate exponential backoff by doubling the delay between successive retry attempts. Ultimately, we capture System.CalloutException and initiate a retry of the callout in the event of an exception.

Conclusion

Incorporating retry logic for unsuccessful callouts is crucial for enhancing reliability and error handling in Salesforce Apex. By establishing a maximum retry count, introducing delays between retry attempts, capturing specific exceptions, and incorporating exponential backoff, you can enhance the probability of success in subsequent retries while minimizing API usage. Utilize the provided code snippet in this post to initiate the implementation of retrying failed callouts in Salesforce Apex.