In our last blog post, we talked about Pure Functions speeding up page rendering and logic execution along with Separation of Concern Patterns, where we break down responsibility between each aspect of the backend system, resulting in libraries of reusable code across the organization.
While we always strive to produce quality projects and regression-tested code, no system is ever 100% foolproof. Here at GyanSys, we take pride in ensuring our client’s success, and we believe that while it is critical to reduce errors proactively, it is crucial to create the tools required to react when problems arise.
When it comes to error handling, Salesforce provides a couple of options like Apex Debug Logs and Salesforce Shield. However, specific use cases need additional handling, where we also use a custom error-handling framework. Each of these solutions comes with its own feature set and trade-offs, and sometimes we must leverage one or more solutions in parallel to suit our particular business requirements. With these three solutions, we will evaluate them based on the following three requirements:
We are all familiar with the famous Apex debug statements. This is a fantastic tool that allows developers to log database operations, and system processes, and try/catch errors during transactions. Debug logs can also contain non-code information, such as database changes, HTTP callouts, workflows, approval processes, and more. These logs are stored in the standard ApexLog objects inside Salesforce and require no additional customization.
Salesforce Shield is a set of security tools that Salesforce launched back in 2015. Within this set, Event Monitoring provides features for Admins and Developers to monitor the state of their Org. These logs are in the EventLogFile, and they can capture entire categories of events such as Logins, Visualforce page loads, Apex executions, API calls, and more. Event Monitoring can be configured without any development effort and is a comprehensive monitoring tool that captures significant use cases.
Out-of-box solutions won’t cover all the use cases, to handle certain scenarios we’ve designed a custom framework that leverages Platform Event to log errors to a Custom Object. With this approach, not only can we generate standard Salesforce Reports to understand the impact and the stability of our system better, but it also provides an endpoint for all external systems to listen to, allowing for further customizations and enhancements at the client’s discretion.
As developers on the platform, we understand that all clients utilize the limits of their org differently. If Platform Events are not feasible due to existing implementations, we also recommend a similar approach but with Push-Topics or Future calls.
We listed three different solutions, and as you can probably tell, they all come with their respective trade-offs. One solution is not necessarily better than the other, and no one solution will tick all the boxes. Apex debug logs are great, but they are not at all reliable for long-term monitoring. Event monitoring is very reliable, but per its name, its core use case is for monitoring the Org, not handling errors. Our custom framework is very flexible, but it comes with specific resource usage that may be non-feasible for certain clients.
private static Error_Log_Event__e createError(String description, String message, String source) {
// make sure input length does not exceed field max length
final Integer DESCRIPTION_MAX_LENGTH = Schema.SObjectType.Error_Log_Event__e.fields.Description__c.getLength();
final Integer MESSAGE_MAX_LENGTH = Schema.SObjectType.Error_Log_Event__e.fields.Message__c.getLength();
// populate log event object
Error_Log_Event__e newLog = new Error_Log_Event__e();
newLog.Description__c = description.length() <= DESCRIPTION_MAX_LENGTH ?
description : description.substring(0,DESCRIPTION_MAX_LENGTH);
newLog.Message__c = message.length() <= MESSAGE_MAX_LENGTH ?
message : message.substring(0,MESSAGE_MAX_LENGTH);
newLog.Source__c = source;
return newLog;
}
public static void publishError(String description, String message, String source) {
// create and publish error log event
Error_Log_Event__e newLog = createError(description, message, source);
EventBus.publish(newLog);
}
trigger ErrorLogEventTrigger on Error_Log_Event__e (after insert) {
ErrorLogEventTriggerHandler.createErrorLogs(Trigger.new);
}
public static void createErrorLogs(List<Error_Log_Event__e> logEvents) {
// Construct and inserts log record
List<Error_Log__c> logs = new List<Error_Log__c>();
for(Error_Log_Event__e logEvent : logEvents){
Error_Log__c log = new Error_Log__c();
log.Description__c = logEvent.Description__c;
log.Message__c = logEvent.Message__c;
log.Source__c = logEvent.Source__c;
logs.add(log);
}
insert logs;
}
At GyanSys, we recommend the combination of Salesforce Shield + Custom Framework because it offers the maximum coverage and flexibility. Event monitoring allows DevOps and Admins alike to monitor the health and security of the entire org. At the same time, our custom framework ensures all apex exceptions are logged reliably with full traceability. While Salesforce Shield can be purchased and implemented with minimum effort, the Custom Framework comes with a few additional considerations.
Our methodology is precise to ensure fewer mistakes and helps our clients do less work in the future, with or without us. Coders are builders first. That’s why we need a steady foundation to build off of to solve complex problems. If you are interested in more details about our custom logging framework, feel free to contact us. If you share the same sense of responsibility and passion for the work that you do, join our team.