Mastering Error Logging and Exception Handling in Salesforce

Created July 30, 2024

In today’s fast-paced digital landscape, robust error logging and exception handling are crucial for maintaining the integrity and performance of applications. Salesforce, as one of the leading cloud-based platforms, provides several features and best practices for managing errors effectively. In this blog, we’ll explore the importance of error logging and exception handling in Salesforce, along practical tips and techniques to implement them in your organization.

Why Error Logging and Exception Handling Matter

When developing applications on Salesforce, unexpected errors and exceptions can significantly impact the user experience, business processes, and overall system performance. Proper error logging and exception handling allow developers to:

Identify and Diagnose Issues:

By logging errors, you can gain insights into what went wrong and where making it easier to troubleshoot and resolve issues.

Enhance User Experience:

Properly handled exceptions can provide users with meaningful feedback, guiding them on how to correct their actions instead of encountering cryptic error messages.

Improve System Reliability:

A robust error handling mechanism helps maintain system stability and reliability, preventing cascading failures that can disrupt business operations.

Facitate Continuous Improvement:

Analyzing logged errors can help identify patterns and areas for improvement in your application, leading to better design and development practices.

Best Practices for Error Logging in Salesforce

Use Custom Exception Classes:

Salesforce allows you to create custom exception classes to handle specific types of errors. By extending the standard Exception class, you can define your own error that can be caught and handled differently based on the context.

public class CustomException extends Exception {}

Implement Try-Catch Blocks:

Always wrap your code in try-catch blocks to handle exceptions gracefully. This prevents unhandled exceptions from crashing your application and allows you to log errors effectively.

try       // Your code here
} catch (CustomException e) {
    // Log the exception
}

Utilize Salesforce Debug Logs:

Salesforce provides debug logs that can be useful for tracking down errors. You can set the log levels to capture specific types of information, including exceptions. Use the Developer Console or set up debug logging for specific users to detailed information about errors.

Leverage the System.debug() Method:

Use the System.debug() method to log meaningful messages and variable values when exceptions occur. This helps you understand the context of the error.

catch (Exception e) {
    System.debug('Error occurred: ' + e.getMessage());
}

Create a Centralized Error Logging System:

Instead of scattering your logging throughout your codebase, consider creating a centralized logging utility. This utility can handle logging to a custom object, external logging service, or even send alerts to administrators.

public class ErrorLogger {
    public static void logError(String errorMessage, Exception e) {
        // Code to log the error message and exception details to a custom object
    }
}

Monitor and Analyze Logged Errors:

Regularly review the logged errors to identify trends and common issues. This analysis can help you proactively address recurring problems and improve the overall stability of your application.

Exception Handling Strategies

User-Friendly Error Messages:

When an error occurs, provide users with clear and actionable error messages. Avoid technical jargon and suggest steps they can take to resolve the issue.

Graceful Degradation:

Design your application to handle failures gracefully. For instance, if a specific feature fails, ensure that the rest of the application remains functional instead of crashing entirely.

Use of @AuraEnabled with Exception Handling in Lightning Components:

When working with Lightning components, use @AuraEnabled methods with proper exception handling to manage errors in asynchronous calls. This allows you to return error messages to the client-side components.

@AuraEnabled
public static String someMethod() {
    try {
        // Your logic here
    } catch(Exception e) {
        throw new AuraHandledException('An error occurred: ' + e.getMessage());
    }
}

Custom Error Pages:

For Visualforce pages, consider creating custom error pages to handle exceptions gracefully. This ensures that users see a friendly error page rather than a generic error message.

Alerting and Notifications:

Implement a system to alert developers or administrators when critical errors occur. This can be done through email notifications or integration with external monitoring tools.

Let’s create a practical example that demonstrates error logging and exception handling in Salesforce using Apex. We’ll create a simple utility class for error logging, a custom exception class, and a sample service class that performs some operations while using proper exception handling.

Step 1: Create a Custom Exception Class

First, we’ll create a custom exception class to handle specific business logic errors```apex public class BusinessLogicException extends Exception {}

Step 2: Create an Error Logging Utility Class

Next, we’ll create a utility class that will handle logging errors to a custom object. For this example, let's assume we have a custom object called Error_Log__c with fields Error_Message__c, Stack_Trace__c, and Created_Date__c.

public class ErrorLogger {
    public static void logError(String errorMessage, String stackTrace) {
        Error_Log__c errorLog = new Error_Log__c();
        errorLog.Error_Message__c = errorMessage;
        errorLog.Stack_Trace__c = stackTrace;
        errorLog.Created_Date__c = System.now();
        
        {
            insert errorLog;
        } catch (Exception e) {
            System.debug('Failed to log error: ' + e.getMessage());
        }
    }
}

Step 3: Create a Service Class with Error Handling

Now, let’s create a service class that performs some operations and uses the error logging utility. In this example, we’ll simulate a scenario where error might occur, such as a division by zero.

public class CalculationService {
    public static Decimal performDivision(Decimal numerator, Decimal denominator) {
        try {
            if (denominator == 0) {
                throw new BusinessLogicException('Denominator cannot be zero.');
            }
            return numerator / denominator;
        } catch (BusinessLogicException ble) {
 // Log the business logic error
            ErrorLogger.logError(ble.getMessage(), ble.getStackTraceString());
            throw new AuraHandledException('A business logic error occurred: ' + ble.getMessage());
        } catch (Exception e) {
            // Log general exceptions
            ErrorLogger.logError('An unexpected error occurred: ' + e.getMessage(), e.getStackTraceString());
            throw new AuraHandledException('An unexpected error occurred. Please contact support.');
        }
    }
}

Step 4: Using the Service Class in an Apex Controller

Finally, let’s create a simple Apex controller that uses the CalculationService to perform division and handles any errors that might arise.

public with sharing class CalculationController {
    @AuraEnabled
    public static Decimal divideNumbers(Decimal numerator, Decimal denominator) {
        try {
            return CalculationService.performDivision(numerator, denominator);
        } catch (AuraHandledException e) {
            // Handle UI-friendly error messages
            throw e; // Re-throw the AuraHandledException to be captured in the Lightning component
        }
    }
}

Step 5: Lightning Component Example

If you want to see how this can be integrated into a Lightning component, here’s a simple example of how you might call the divideNumbers method.

<aura:component controller="CalculationController">
    <aura:attribute name="numerator" type="Decimal" />
    <aura:attribute name="denominator" type="" />
    <aura:attribute name="result" type="Decimal" />
    <aura:attribute name="errorMessage" type="String" />

    <lightning:input label="Numerator" value="{!v.numerator}" />
    <lightning:input label="Denominator" value="{!v.denominator}" />
    <lightning:button label="Divide" onclick="{!c.handleDivide}" />

    <aura:if isTrue="{!not(empty(v.result))}">
        <p>Result: {!v.result}</p>
    </aura:if>

    <aura:if isTrue="{!not(empty(v.errorMessage))}">
        <p style="color:red;">Error: {!v.errorMessage}</p>
 </aura:if>
</aura:component>

Client-side Controller for the Lightning Component

({
    handleDivide: function(component, event, helper) {
        var numerator = component.get("v.numerator");
        var denominator = component.get("v.denominator");

        var action = component.get("c.divideNumbers");
        action.setParams({ numerator:                if (errors && errors[0] && errors[0].message) {
                    component.set("v.errorMessage", errors[0].message);
                }
            }
        });

        $A.enqueueAction(action);
    }
})

In this example, we demonstrated how to implement error logging and exception handling in Salesforce using Apex and Lightning components. Key points included:

Creating custom exceptions to handle specific errors.
Using a centralized logging utility to log errors to a custom object.
Implementing try-catch blocks to handle exceptions gracefully.
Providing user-friendly error messages in a Lightning component.
By following these practices, you can create a more robust Salesforce application that gracefully handles errors and provides meaningful feedback to users.

Conclusion

Effective error logging and exception handling are essential for any Salesforce application. By adopting best practices and leveraging Salesforce’s powerful features, you can enhance the reliability and user experience of your applications. Remember, every error is an opportunity for learning and improvement, so invest the time in building a robust error management system that can evolve with yours needs. With the right approach, you can ensure that your Salesforce environment remains a reliable and efficient platform for all users.